NoClassDefFound error in plugin

Hey all in Servoy-Land, got a bit of a brain bender if anyone has any insights.

Working on a WebServices plugin, and using the Apache Axis2 libraries to generate everything in Eclipse. So far everything works quite well…as long as I’m running it in Developer mode. However, as soon as we try to do anything in client mode, we start running into problems, and get the following error:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/apache/axis2/databinding/ADBBean
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(Unknown Source)
	at java.security.SecureClassLoader.defineClass(Unknown Source)
	at java.net.URLClassLoader.defineClass(Unknown Source)
	at java.net.URLClassLoader.access$000(Unknown Source)
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
	at com.adblocks.plugin.erevision.wrapper.ERevision.getScriptObject(ERevision.java:39)
	at com.servoy.j2db.scripting.i.get(Unknown Source)
	at org.mozilla.javascript.ScriptRuntime.getProp(ScriptRuntime.java:726)
	at org.mozilla.javascript.gen.c658.call(getERevInventoryForLine:103)
	at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1254)
	at org.mozilla.javascript.gen.c657.call(getZoneAvails:120)
	at org.mozilla.javascript.ScriptRuntime.call(ScriptRuntime.java:1254)

The root of the problem seems to be here at com.adblocks.plugin.erevision.wrapper.ERevision.getScriptObject(ERevision.java:39), where I am making my instantiation of the class for the provider. What appears to be going on is that the JNLPClassLoader can’t find a handful (possibly all, but I think it’s only some) of the Axis2 Libraries. The Axis2 libraries are located in a sub folder of the plugins: \plugins\Axis2

In the past i have been able to solve this by running some code like the following

ClassLoader orig = Thread.currentThread.getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
...
//code here
...
Thread.currentThread().setContextClassLoader(orig);

However, that doesn’t seem to be working this time. I’ve also tried a similar iteration of the above code, but switching to the parent ClassLoader of the current one, also to no avail.
After scouring the forums, I found that some people had luck by placing all subfolder libraries int he root of the plugin folder. I find this to be a messy solution (there are 59 Axis libraries!), but was willing to try it out. That also got me nowhere.
Then I tried creating a custom JNLP file for the plugin that included all the Axis libraries explicitly in the resources section (much as I have seen in Marcel’s and Patrick’s plugins). I had high hopes for this one, but, again, I was disappointed.

So that leaves me here, not quite knowing what to do from here, and hoping for some help. Thanks in advance for any tips!

Are you executing the WebService clientside or serverside?

If you do this clientside (in the Smart Client), you need to specify a jnlp file for your plugin jar, so all Axis2 libs are also downloaded to the client.

But, unless you have a very good reason to execute the webservice in the client, I suggest you don’t do this and execute the webservice serverside. This means a couple of things:
1: you don’t need to worry about getting all the needed jars to the client in the proper version etc.
2: because no jars need to go to the client, the client will start faster and the client will have less footprint
3: if the webservice you call has any restrictions on who can connect, you only have to arrange it for the server, not for all possible locations that clients start from

I never had the need to do stuff with classloaders when creating a plugin that utilizes the Axis2 libs. Just place the in a subdirectory of the plugins folder and execute your webservices serverside.

Paul

jgarfield:
Then I tried creating a custom JNLP file for the plugin that included all the Axis libraries explicitly in the resources section (much as I have seen in Marcel’s and Patrick’s plugins). I had high hopes for this one, but, again, I was disappointed.

that should have worked fine see for example the http plugin:

<jnlp spec="1.0+"
      codebase="%%serverURL%%"
      href="/servoy-client/plugins/http.jar.jnlp">
   <information> 
      <title>Servoy Client Plugins</title> 
      <vendor>Servoy and Others</vendor>
      <offline-allowed/>
   </information>
   <resources>
      <jar href="/plugins/http.jar" download="eager" part="http" version="%%version%%"/>
      <jar href="/lib/commons-httpclient.jar" download="%%loadmethod%%" part="httpclient" version="3.0"/>
      <jar href="/lib/commons-codec.jar" download="%%loadmethod%%" part="codec" version="1.3"/>
      <package name="org.apache.commons.httpclient.*" part="httpclient" recursive="true"/>      
      <package name="org.apache.commons.codec.*" part="codec" recursive="true"/>      
   </resources>
   <component-desc/>
</jnlp>

Did you try to flush the clients caches so that it really got the latest jnlp files (and a restart of the server)?

johan

pbakker:
But, unless you have a very good reason to execute the webservice in the client, I suggest you don’t do this and execute the webservice serverside. This means a couple of things:
1: you don’t need to worry about getting all the needed jars to the client in the proper version etc.
2: because no jars need to go to the client, the client will start faster and the client will have less footprint
3: if the webservice you call has any restrictions on who can connect, you only have to arrange it for the server, not for all possible locations that clients start from

BTW, this also mean that you need to create a server plugin, and possibly a client plugin that will interact with your server plugin.
See the mail.jar plugin that contains an example of this or the servoy_jasperreports.jar with source on google code.

jcompagner:
Did you try to flush the clients caches so that it really got the latest jnlp files (and a restart of the server)?

Also, if you decide to go with a client side plugin, which I agree with Paul shouldn’t be necessary, did you check that the jnlp has the same name as your jar + “.jnlp”?

For example, for the jnlp of a “mysuper_plugin.jar” to be used, it needs to be called “mysuper_plugin.jar.jnlp” exactly.

Thanks for all the input. I think in the long run we’re going to move forward with the server side plugin idea.

At the moment I’m still trying to figure out why my jnlp isn’t working.

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="%%serverURL%%" href="/servoy-client/plugins/eRevisions.jar.jnlp">
   <information>
      <title>eRevisions Plugin</title>
      <vendor>adBlocks Inc.</vendor>
      <offline-allowed/>
   </information>
   <resources>
      <jar href="/plugins/eRevisions.jar" part="wrapper" download="eager" version="2"/>
      <jar href="/plugins/Axis2/activation-1.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/annogen-0.1.0.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axiom-api-1.2.7.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axiom-dom-1.2.7.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axiom-impl-1.2.7.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-adb-1.4.jar part="adb" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-adb-codegen-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-ant-plugin-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-clustering-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-codegen-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-corba-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-fastinfoset-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-java2wsdl-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-jaxbri-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-jaxws-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-jaxws-api-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-jibx-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-json-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-jws-api-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-kernel-1.4.jar part="kernel" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-metadata-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-mtompolicy-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-saaj-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-saaj-api-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-spring-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/axis2-xmlbeans-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/backport-util-concurrent-3.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/commons-codec-1.3.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/commons-fileupload-1.2.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/commons-httpclient-3.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/commons-io-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/commons-logging-1.1.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/geronimo-annotation_1.0_spec-1.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/geronimo-stax-api_1.0_spec-1.0.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/httpcore-4.0-beta1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/httpcore-nio-4.0-beta1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/jalopy-1.5rc3.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/jaxb-api-2.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/jaxb-impl-2.1.6.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/jaxb-xjc-2.1.6.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/jaxen-1.1.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/jettison-1.0-RC2.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/jibx-bind-1.1.5.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/jibx-run-1.1.5.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/log4j-1.2.15.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/mail-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/mex-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/neethi-2.0.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/soapmonitor-1.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/version-1.4-sources.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/woden-api-1.0M8.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/woden-impl-dom-1.0M8.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/wsdl4j-1.6.2.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/wstx-asl-3.2.4.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/xalan-2.7.0.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/xercesImpl-2.8.1.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/xml-apis-1.3.04.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/xml-resolver-1.2.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/xmlbeans-2.3.0.jar part="axis" download="eager" version="2"/>
      <jar href="/plugins/Axis2/XmlSchema-1.4.2.jar part="axis" download="eager" version="2"/>
	<package name="org.apache.axis2.*" part="kernel" recursive="true"/>
	<package name="org.apache.axis2.databinding.*" part="adb" recursive="true"/>
   </resources>
   <component-desc/>
</jnlp>

is what I have right now (I know I’ve got a ton of extra Axis Libs in there, just haven’t taken the time to weed it all out yet :oops: )

I was missing the “package” options before, and thought adding them in would fix things (especially since the library it claims to be missing is int he databinding package), but I keep getting the same error. Yes, even after restarting the server, clearing out the cache, deleting the .servoy folder etc.

jgarfield:

<?xml version="1.0" encoding="utf-8"?>
eRevisions Plugin adBlocks Inc. > ```

Wow! Man, you really have to weed out!
Your users are really going to hate you with all this…

I can see right now that some of the libs are already part of the download, like activation, the commons-*, log4j, mail, maybe some others depending on the plugins you have installed.

And what I fail to understand is why you need all these libs, most of them are server-side libs. Are you going to transform the smart client into a smart server?

I think you should get back to the axis docs and look for client dependencies, and load only those who have not already been loaded by other Servoy’s plugins/beans/lib. You will definitely run into jar collision with all that in your jnlp.

can you remove the part=“xxx” and then the package section below?
they are not really making sense in that jnlp anyway because you have a part “axis” in the jar but now packages that point to that and you have packages with a part that point to no jar…

Besides that it is possible that some dependencies are not correct here or better said maybe colliding (other plugins or the base servoy)

What you also could do is look into the cache of javaws and see if all the jars are really downloaded and are there (so the client does download them all)
the cache is a bit cryptic so its not easy to find everything.

Thanks for all the input guys. IN The end we went with the server plugin route, and everything has resolved itself nicely.