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.
Related
A related problem: Get the class path from the context class loader (of WebLogic for instance)
This is already solved in How to set up the context class loader's classpath for runtime compilation?.
Current problem: Get the same (proper) class path used to run a web app
Reflectively calling the "getClassPath()" method works but it returns a dirty classpath containing unanted modules from $ORACLE_HOME/oracle_common/modules directory.
Problematic scenario:
Deploy a web app "Parent" in WebLogic // <- works
Get the context class path (it's a String object) by reflexively calling "getClassPath()" // <- works
Fork a process out of the main "Parent" process and run it using the context class path // <- fails
04:36:45,238 [Thread-41] ERROR ChildProcess - Exception in thread "main" java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapp
er.configOverride(Ljava/lang/Class;)Lcom/fasterxml/jackson/databind/cfg/MutableConfigOverride;
Explanation
While the context class path contains the necessary dependencies for the child process to run, they are overshadowed by WebLogic's own dependencies. The result is runtime failures such as the one shown above.
Workaround
a) Use a new version of WebLogic server that hopefully would use newer versions of the artifacts needed by the child process // risky endeavour
b) Manually process the context class path and remove any artifact that would shadow their more-recent counterparts
Solution b) looks more practical, but I don't like it for meany reasons:
The reflexive call to "getClassPath" returns a String, and looking for artifact's names in Strings feels frail and weak
I wouldn't know what shadows what. WebLogic prepends its weird artifacts at the start of the string before listing the web app's own dependencies.
Only weblogic.xml has info on the web app's package preferences. I wish I could mimic how WebLogic processes this file to run the web app (Parent) and use that to properly run the child process
It seems to me that forking a process out from a web app running in WebLogic does not enjoy the same package preferences expressed in "weblogic.xml" that the web app (Parent) enjoyed when it was deployed and started running.
Other than the above suggestions, I am welcoming of any stronger solutions
I am new to Jython and Python, trying to build a prototype that makes use of Python code to be called from within Java. The code I am developing works in Jetty and in standalone mode (running java -jar from the command line), but not when deployed to weblogic.
How can I make weblogic(10.3.5) server/Jython recognize the Lib folder within jython-standalone-2.5.4-rc1.jar?
My Java code uses the JythonObjectFactory to invoke python modules as outlined in the Jython book:
http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html
The Python modules are using external libraries like csv, logging etc. that are not packaged with jython.jar, hence I am using jython-standalone jar.
The java code includes an interface that would define the class type of the first invoked py module from within java. The interface and the input and output (to python modules) type classes are in a package structure as com.abc.xpackage. and the py modules exist at the root of this package. A controller layer calls the objectfactory and in turn executes the python code thus:
JythonObjectFactory calFactory = new JythonObjectFactory(CalcType.class, "Calculate", "Calculate");
CalcType engine = (CalcType)calFactory.createObject();
output = engine.execute(input);
The entire code is bundled as a jar file which would become part of a web application deployed on weblogic. The code was compiled with maven (with jython dependencies included in the repository) and runs fine on the included Jetty runtime within eclipse.
When deployed on weblogic, however, I get a "ImportError: no module named csv" error.
To analyze what is happening, I tried printing the Jython system state path on weblogic and the standalone environment/Jetty. What I found is,
on Jetty, the system path consists of the following:
C:\.m2\repo\org\python\jython\jython-standalone-2.5.3-rc1.jar\Lib, ____classpath__, ____pyclasspath__
on Weblogic, printing the system path by default shows the following:
____classpath__, ____pyclasspath__
I tried forcing the inclusion of the missing path using the code as follows:
public JythonObjectFactory(PySystemState state, Class interfaceType, String moduleName, String className) {
String pathToAppend = new File(state.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getAbsolutePath()+"\\Lib";
state.path.insert(0, new PyString(pathToAppend));
state.path.append(new PyString(pathToAppend));
System.out.println("Jython sys path: "+state.path);
Please note, I prepended as well as appended the path in different trials. The sys path on weblogic now displays the following:
Jython sys path: ['C:\\wldomain\\wls135\\servers\\cgServer\\tmp\\app-1\\war\\WEB-INF\\lib\\jython-standalone-2.5.4-rc1.jar\\Lib', '__classpath__', '__pyclasspath__/', 'C:\\wldomain\\wls135\\servers\\cgServer\\tmp\\app-1\\war\\WEB-INF\\lib\\jython-standalone-2.5.4-rc1.jar\\Lib']
I am still getting ImportError despite this forcing of sys path. Please help why this works in a local environment, and not on weblogic, and if there is any configuration I am missing. Apologize for the rambling long post, I did not know how to explain the problem better. I will try and include any code/artifacts as needed.
Based on a comment(by Lassi) on the blog post below:
http://www.petervannes.nl/files/e1c3c56d15d25dcfd4adb5397a9ef71e-53.php
The jython issue was resolved after explicitly adding the Lib folder python.path to the weblogic startup script as a JAVA_OPTION.
In my case I added the exploded Lib folder to the domain server lib, but based on my test this works also from within the jython jar. Both the following JAVA_OPTIONS worked:
-Dpython.path=C:\wldomain\wls135\lib\Lib
-Dpython.path=C:\wldomain\wls135\lib\jython-standalone-2.5.4-rc1.jar\Lib
The programmatic way of sys.path.append worked for the local environment(jetty) but did not seem to work for weblogic.
Validation framework which has been rolled up as part of the JEE6 spec (WL12). Both the WL10 and WL12 versions of our application were deployed with the following open source libraries:
JSR-303 / validation-api.jar (version 1.0)
Hibernate Validator (version 4.2.0)
However, the libraries are also bundled with WL 12 (modules directory). Note that the Hibernate Validator version is slightly different.
modules.javax.validation_1.0.0.jar
hibernate.validator_4.1.0.jar
With our WL12 run we are getting below exception:
javax.validation.ValidationException: Unable to get available provider
Attempted Solutions
Our next attempt was to use the WebLogic FilteringClassLoader to prefer the libraries from our application (APP-INF/lib directory) by specifying them in the weblogic-application.xml file (i.e. choose our versions over WebLogic’s). We were already doing this for several other open source libraries in WL10:
<prefer-application-packages>
<package-name>com.google.common.*</package-name>
<package-name>org.apache.commons.lang.*</package-name>
<package-name>org.apache.commons.logging.*</package-name>
<package-name>org.apache.commons.beanutils.*</package-name>
<package-name>org.apache.commons.collections.*</package-name>
<package-name>antlr.*</package-name>
<package-name>javax.validation.*</package-name>
<package-name>org.hibernate.validator.*</package-name>
</prefer-application-packages>
After making that change, our application experienced the following run-time error trying to process any request that makes use of the validation framework:
javax.validation.ValidationException: Unable to get available provider resolvers.
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:259)
at web20.hibernate.validation.ValidatorFactoryConfigurator.getValidatorFactory(ValidatorFactoryConfigurator.java:39)
at web20.hibernate.validation.ValidationHandlerImpl.handleHibernateValidations(ValidationHandlerImpl.java:180)
at web20.hibernate.validation.ValidationHandlerImpl.performValidation(ValidationHandlerImpl.java:255)
at web20.hibernate.validation.ValidationHandlerImpl.validateAndFormatMessages(ValidationHandlerImpl.java:302)
at web20.hibernate.validation.ValidationHandlerImpl.validateUsingHibernateGroups(ValidationHandlerImpl.java:113)
at service.serviceapp.performValidations(serviceapp.java:392)
at service.serviceapp.performValidations(serviceapp.java:379)
at service.TransactionalServiceImpl.search(TransactionalServiceImpl.java:300)
Given that Bean Validation is part of the EE standard, I assume there is some code Bean Validation integration code which causes the problem. I see two potential solutions:
Patch the WL instance and upgrade to the Validator version you want to use
Try writing your own ValidationProvider. Internally it could just delegate to the Hibernate Validator classes. If you then add a validation.xml to your application, specifying your custom provider, WL should bootstrap this one. TBH, I don't know whether this will work. There are many unknowns and I don't know enough about the integration of WL and Bean Validation.
Personally, I think I would just try to upgrade the Validator version used in WL.
I'm trying to use cayenne within an Axis2 service (compiled as an .aar file).
I was able to make the service locate my cayenne jar but when I try to make a query on the database, it throws the following exception:
2013-01-15 17:52:38,891 [http-8080-Processor25] DEBUG
org.apache.axis2.transport.http.AxisServlet -
org.apache.axis2.AxisFault: [v.3.0.2 Jun 11 2011 09:52:20] Error
during Configuration initialization. [v.3.0.2 Jun 11 2011 09:52:20]
[org.apache.cayenne.conf.DefaultConfiguration] : Domain configuration
file "cayenne.xml" is not found.
I've been trying to put the cayenne.xml file everywhere (/lib /WEB-INF/lib /WEB-INF/classes though I only had hope for the first one).
Could someone please advise me on how to proceed?
Is it possible to force cayenne to look for the cayenne.xml file in the /lib directory of my .aar ?
Is it possible to print the classpath that is used by the service's classLoader (I understand that each service should have its own classLoader).
While I am no Axis2 expert, from my theoretical understanding of its class loading mechanism, I see two options:
Ensure that cayenne-server.jar and cayenne.xml are loaded by the same ClassLoader (cayenne-server.jar should be in /WEB-INF/lib, while cayenne.xml - in /WEB-INF/classes/),
Set current thread classloader in your Axis code in the place where you bootstrap Cayenne, so that DefaultConfiguration could locate the XML files:
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
I am trying to setup some boiler plate code in my local workspace which uses weblogic10.3. I have a documentation that asks me to import Content.jar from /wlportal_10.3/content-mgmt/lib into window->preferences-->Weblogic-->Shared Library which I did. However when I try to deploy portlet this is the error am getting
Error Deployer BEA-149107 An attempt was made to deploy library 'content' with specified specification version '10.3.2' and implementation version '10.3.2 '. However, the library manifest has specification version '10.3.2' and implementation version '10.3.2'