Eclipse plugin HttpServletRequest在类加载器中不可见

Eclipse plugin HttpServletRequest在类加载器中不可见,eclipse-plugin,osgi,jax-rs,apache-wink,amdatu,Eclipse Plugin,Osgi,Jax Rs,Apache Wink,Amdatu,我试图在OSGI中运行ApacheWink,并将Felix白板注册资源用作服务。在极简主义OSGI环境中,该捆绑包按预期工作。但是,随后我将捆绑包移动到EclipseEquinox环境中,在那里我正在开发一个依赖于它的插件。我开始出现这个错误 May 22, 2013 11:19:59 AM org.apache.wink.server.internal.application.ApplicationProcessor processWinkApplication SEVERE: An exce

我试图在OSGI中运行ApacheWink,并将Felix白板注册资源用作服务。在极简主义OSGI环境中,该捆绑包按预期工作。但是,随后我将捆绑包移动到EclipseEquinox环境中,在那里我正在开发一个依赖于它的插件。我开始出现这个错误

May 22, 2013 11:19:59 AM org.apache.wink.server.internal.application.ApplicationProcessor processWinkApplication
SEVERE: An exception occurred during processing of the com.yarcdata.rest.Repositories instance. This instance is ignored.
 java.lang.IllegalArgumentException: interface javax.servlet.http.HttpServletRequest is not visible from class loader
at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:461)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:690)
at org.apache.wink.common.internal.registry.ContextAccessor.getContextFromAccessor(ContextAccessor.java:92)
我想我已经安装了所有必需的捆绑包,如果我开始寻找导出HttpServletRequest的捆绑包,我会看到:

g! lb | grep ervlet
311|Resolved   |    4|Servlet API Bundle (3.0.0.v201112011016)
394|Starting   |    4|Http Services Servlet (1.1.300.v20120912-130548)
444|Resolved   |    4|Jetty :: Servlet Handling (8.1.3.v20120522)
578|Resolved   |    4|jersey-servlet (1.12.0)
580|Resolved   |    4|jersey-servlet (1.17.1)
588|Active     |    4|Java Servlet API (3.0.1)
589|Resolved   |    4|javax.servlet.api (2.5.0)
590|Resolved   |    4|javax.servlet.jstl (1.1.2)
622|Active     |    4|Servlet Specification API (2.5.0)
678|Resolved   |    4|Spring Web Servlet (2.5.6)

g! bundle 588
javax.servlet-api_3.0.1 [588]
Id=588, Status=ACTIVE      Data Root=/wspaces/tbcPlugin/.metadata/.plugins/org.eclipse.pde.core/Eclipse Application/org.eclipse.osgi/bundles/588/data
"No registered services."
No services in use.
Exported packages
  javax.servlet; version="3.0.0"[exported]
  javax.servlet.descriptor; version="3.0.0"[exported]
  javax.servlet.annotation; version="3.0.0"[exported]
  javax.servlet.http; version="3.0.0"[exported]
No imported packages
No fragment bundles
Named class space
  javax.servlet-api; bundle-version="3.0.1"[provided]
No required bundles
因此,由于HttpServletRequest的完整包是javax.servlet.http.HttpServletRequest,我希望bundle 588处于活动状态,以解决Wink的问题。它处于活动状态并导出包,是否需要其他内容?让我们检查一下它正在查找的版本:

g! lb | grep mdatu
  595|Resolved   |    4|Amdatu Web - JAX RS (1.0.0)
  596|Active     |    4|Amdatu Web - Apache Wink Application (1.0.1)

g! bundle 596
  org.amdatu.web.rest.wink_1.0.1 [596]
  Id=596, Status=ACTIVE      Data Root=/wspaces/tbcPlugin/.metadata/.plugins/org.eclipse.pde.core/Eclipse Application/org.eclipse.osgi/bundles/596/data
  "Registered Services"
    {org.amdatu.web.rest.jaxrs.JaxRsSpi}={service.id=139}
    {javax.servlet.Servlet}={init.applicationConfigLocation=/conf/application.properties, alias=/myresource, service.id=140}
    {javax.servlet.Servlet}={init.applicationConfigLocation=/conf/application.properties, alias=/protocol, service.id=141}
    {javax.servlet.Servlet}={init.applicationConfigLocation=/conf/application.properties, alias=/repositories, service.id=142}
    {org.osgi.service.cm.ManagedService}={service.pid=org.amdatu.web.rest.wink, org.amdatu.tenant.pid=org.amdatu.tenant.PLATFORM, service.id=143}
 Services in use:
    {java.lang.Object}={osgi.command.function=[confapply], osgi.command.scope=equinox, service.id=110}
 ...
  No exported packages
  Imported packages
    javax.activation; version="0.0.0"<org.eclipse.osgi_3.8.2.v20130124-134944 [0]>
    javax.annotation; version="0.0.0"<org.eclipse.osgi_3.8.2.v20130124-134944 [0]>
    javax.servlet; version="3.0.0"<javax.servlet-api_3.0.1 [588]>
    javax.servlet.http; version="3.0.0"<javax.servlet-api_3.0.1 [588]>

看起来您有多个包可以导出Servlet API包,例如588、589和622,可能还有其他包。因此,包导入的包可能与apachewink包导入的包不同。在正常的Java类加载规则下,两个包只有在名称相同且由相同的类加载器加载时才被认为是相同的;这在OSGi下意味着它们需要通过相同的包导出

Wink报告您没有servlet包的可见性。。。它真正的意思是,您不能看到它使用的同一个servlet包


虽然OSGi可以处理同一个包的多个版本的导出,但是如果您尝试只从一个包导出每个包,那么您的工作就会轻松得多。因此,首先,您应该去掉所有这些冗余的API包

看起来您有多个包导出Servlet API包,例如588、589和622,可能还有其他包。因此,包导入的包可能与apachewink包导入的包不同。在正常的Java类加载规则下,两个包只有在名称相同且由相同的类加载器加载时才被认为是相同的;这在OSGi下意味着它们需要通过相同的包导出

Wink报告您没有servlet包的可见性。。。它真正的意思是,您不能看到它使用的同一个servlet包


虽然OSGi可以处理同一个包的多个版本的导出,但是如果您尝试只从一个包导出每个包,那么您的工作就会轻松得多。因此,首先,您应该去掉所有这些冗余的API包

您可以在ContextAccessor.java中找到以下代码片段:92

(T)Proxy.newProxyInstance(Injectable.class.getClassLoader(),
                                  new Class[] {contextClass},
...
正如您所看到的,Injectable类的类加载器也在wink-common.jar中使用。但是,如果查看wink-commons.jar的MANIFEST.MF文件,您将看到该模块没有导入javax.servlet.http包


我不知道这门课的真正逻辑。如果程序员没有很好的理由使用类加载器加载的可注入类,那么最好使用contextClass的类加载器来生成代理。您可以向wink开发人员询问此事。

您可以在ContextAccessor.java中找到以下代码片段:92

(T)Proxy.newProxyInstance(Injectable.class.getClassLoader(),
                                  new Class[] {contextClass},
...
正如您所看到的,Injectable类的类加载器也在wink-common.jar中使用。但是,如果查看wink-commons.jar的MANIFEST.MF文件,您将看到该模块没有导入javax.servlet.http包


我不知道这门课的真正逻辑。如果程序员没有很好的理由使用类加载器加载的可注入类,那么最好使用contextClass的类加载器来生成代理。你可以向wink开发者询问此事。

这很有道理,而且有助于我集中精力。有没有办法询问OSGI当前运行的哪个包导出给定的包?如果您只有Gogo附带的非常基本的命令,那么就不容易了。你必须检查c osgi.接线.软件包。。。这将列出所有捆绑包的所有导出,然后您可以对结果进行文本搜索。如果您使用的是扩展shell,那么您可能可以访问更强大的包列表命令。。。试试内置的帮助。这很有意义,可以帮助我集中精力。有没有办法询问OSGI当前运行的哪个包导出给定的包?如果您只有Gogo附带的非常基本的命令,那么就不容易了。你必须检查c osgi.接线.软件包。。。这将列出所有捆绑包的所有导出,然后您可以对结果进行文本搜索。如果您使用的是扩展shell,那么您可能可以访问更强大的包列表命令。。。试试内置的帮助。