繁体   English   中英

为什么我的ORDS servlet不执行,即使我已遵循现有指南?

[英]Why isn't my ORDS servlet executing, even though I've followed the existing guidelines?

我正在编写一个ORDS插件,用于过滤某些请求。 我不是很想让过滤工作,所以我决定遵循Oracle提供的插件API说明。

我已经使用Gradle任务自动配置了大部分构建,该任务自动:

  • 下载WAR
  • 将插件JAR(以前也使用Gradle构建)添加到ORDS
  • 确保正确设置configdir

实际上,这是我自动运行的等价物:

# Assuming the JAR is cURL'd in from somewhere...
java -jar ords.war plugin build/myPlugin.jar
java -jar ords.war configdir /home/makoto/ords-configuration

...并将其部署到我的本地IntelliJ实例。

这是我的servlet的样子。 这很基础。

import oracle.dbtools.plugin.api.di.annotations.Provides;
import oracle.dbtools.plugin.api.http.annotations.Dispatches;
import oracle.dbtools.plugin.api.http.annotations.PathTemplate;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Provides
@Dispatches(@PathTemplate(("/plugin/servlet/")))
public class TestServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("this worked?!");
    }
}

我在文档中相信我应该能够在http:// localhost:8080 / ords / my_schema / plugin / servlet /中访问它,但似乎并非如此。 我反而接受了404:

DispatcherNotFoundException [statusCode=404, reasons=[]]
    at oracle.dbtools.http.entrypoint.Dispatcher.choose(Dispatcher.java:87)
    at oracle.dbtools.http.entrypoint.Dispatcher.dispatch(Dispatcher.java:98)
    at oracle.dbtools.http.entrypoint.EntryPoint$FilteredServlet.service(EntryPoint.java:240)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:73)
    at oracle.dbtools.url.mapping.RequestMapperImpl.doFilter(RequestMapperImpl.java:125)
    at oracle.dbtools.url.mapping.URLMappingBase.doFilter(URLMappingBase.java:103)
    at oracle.dbtools.url.mapping.filter.URLMappingFilter.doFilter(URLMappingFilter.java:148)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.cors.CORSResponseFilter.doFilter(CORSResponseFilter.java:83)
    at oracle.dbtools.http.filters.HttpResponseFilter.doFilter(HttpResponseFilter.java:45)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.errors.ErrorPageFilter.doFilter(ErrorPageFilter.java:94)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.auth.ForceAuthFilter.doFilter(ForceAuthFilter.java:44)
    at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
    at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
    at oracle.dbtools.http.filters.Filters.filter(Filters.java:47)
    at oracle.dbtools.http.entrypoint.EntryPoint.service(EntryPoint.java:82)
    at oracle.dbtools.http.entrypoint.EntryPointServlet.service(EntryPointServlet.java:49)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at oracle.dbtools.rt.web.HttpEndpointBase.dispatchableServices(HttpEndpointBase.java:116)
    at oracle.dbtools.rt.web.HttpEndpointBase.service(HttpEndpointBase.java:81)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

-- snip --

我错过了什么? 我不清楚什么应该是一个非常基本的servlet - 这实际上类似于“Hello World!” 他们提供的例子 - 根本就没有适当注册。

注意:

  • 该架构 ORDS启用。
  • 我用过的两个容器都会发生这个错误; Glassfish和Tomcat。
  • 我没有使用APEX,这似乎是这个产品的常见插件。 我打算将ORDS用作我的数据的RESTful提供程序。
  • @Dispatches路径中的尾部斜杠似乎没有效果; 如果它被删除或者它存在,问题仍然存在。

我正在寻找权威的答案或见解,这里可能会发生什么。 在黑暗中猜测和拍摄对我没有好处,因为我自己一直在修补它,并且我们的修补路径很可能会重叠。


由于我不喜欢在任何问题上添加图片, BalusC建议我检查JAR的内容以确保包含特定的提供者文件。

从这个截图中,似乎有两个 ......

在此输入图像描述

......他们的内容是一样的......

com.foo.bar.baz.bing.servlet.TestServlet
oracle.dbtools.plugin.api.di.AnnotationsProvider

...但是当我去提取JAR并检查文件时,它只包含AnnotationsProvider行。

oracle.dbtools.plugin.api.di.AnnotationsProvider

可是等等! 它变得怪异!

当我挂载JAR以提取单个文件时,我看到很多重复:

在此输入图像描述

...这让我相信, 不知何故 ,旧文件覆盖了较新的文件。

我已经把问题想出来了。 BalusC的建议指出了我正确的方向。

ORDS期望通过名为META-INF/oracle.dbtools.plugin.api.di.providers的文件注册提供程序。 在此文件中是由完全限定名称描述的类的列表,这些类已使用@Provides注释。 任何未出现在那里的课程都不会被ORDS收录。

正如我的问题所强调的那样,我遇到的是JAR中存在的重复文件名。 如果我通过Neovim观察它,我会在一个文件中看到我的FQN类,而在另一个文件中看不到。 如果我通过Nautilus / File Extractor观察它,我只会看到没有我的FQN类的文件。

重复的文件问题原来是冒烟的枪。 为了让我能够使用它,我不得不从我构建的JAR中删除重复项。 在Gradle中,实现这一目标的方法如下:

jar {
   duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

现在,只显示正确的*providers文件,并且我的servlet能够在ORDS中被命中。

我会指出这是一个惊喜; 我没想到任何类型的重复文件要打包在JAR中,ORDS文档也没有预料到这个问题。 我认为这是其他开发者的公平灯塔,要注意这种情况。

我在demo插件JAR的源代码中看到它用SPI注册自己。 这就是WAR中的ORDS核心如何找到它的方式。 ORDS示例文件夹中提供的Ant任务负责在创建JAR时生成必要的SPI文件。 你提到你为此使用了Gradle任务,所以我认为你是自己编写的。

为了验证您的Gradle作业是否也生成了正确的JAR,请提取Gradle生成的插件JAR文件并检查是否存在唯一内容为FQN的/META-INF/oracle.dbtools.plugin.api.di.providers文件您的TestServlet 如果没有,那么WAR中的ORDS核心肯定不会发现它。

您可以通过将PluginDemo servlet源代码替换为您自己的servlet内容,然后按照教程中的说明使用提供的Ant任务构建JAR,来确认插件servlet的源代码是否正确。 如果这样可行,那么它肯定是需要修复的Gradle任务,而不是你的插件servlet。 但是,由于该信息在问题中缺失,因此无法给出详细的答案。 但至少应该把你推向正确的方向,以确定问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM