문제

I'm trying to run Apache Wink in OSGI and using Felix Whiteboard register resources as services. In a minimalist OSGI environment the bundle works as expected. But, then I moved the bundle into an Eclipse Equinox environment where I am developing a plugin that relies on it. The I started getting this error.

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)

I think I have all the required bundles installed, and if I start looking for the bundle that exports HttpServletRequest I see:

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

So, since the full package of HttpServletRequest is javax.servlet.http.HttpServletRequest I would expect bundle 588 being in Active state to solve the problem for Wink. It's active and it exports the package, is there something more required? Let's check to see what version it is looking for:

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]>
도움이 되었습니까?

해결책

It looks like you have multiple bundles that export the Servlet API packages (e.g. 588, 589 and 622, possibly others as well). Therefore the package imported by your bundle may be different from the one imported by the Apache Wink bundle. Under normal Java class-loading rules, two packages are only considered to be "the same" if they have the same name AND are loaded by the same class loader; which under OSGi means they need to be exported by the same bundle.

Wink reports that you don't have visibility of the servlet package... what it really means is that you don't have visibility of the same servlet package that it is using.

Though OSGi can handle multiple versioned exports of the same package, you make your life much easier if you try to export each package from only one bundle. So in the first instance you should get rid of all these redundant API bundles.

다른 팁

You can find the following code snippet at ContextAccessor.java:92

(T)Proxy.newProxyInstance(Injectable.class.getClassLoader(),
                                  new Class[] {contextClass},
...

As you can see the classloader of Injectable class is used that is also in wink-common.jar. However, if you look into the MANIFEST.MF file of the wink-commons.jar you will see that the package javax.servlet.http is not imported by that module.

I do not know the real logic in this class. If the programmer did not have a very good reason to use the classloader loaded Injectable it is probably better to use the classloader of contextClass for proxy generation. You can ask the wink developers about it.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top