Controlling the order of how JARs are loaded in the classpath - java

I'm using GWT 2.4 with gquery-dnd-bundle 1.0.4 so that I can construct trees with drag-and-drop nodes. I've bumped into an annoying bug (http://code.google.com/p/gwtquery-plugins/issues/detail?id=6). The gist of it is I need to guarantee that the file "gquery-dnd-bundle-1.0.4.jar" gets loaded by the classloader at runtime before the gwt-servlet.jar file in my WEB-INF/lib directory.
How can I guarantee this?
I'm using Eclipse Indigo with a GWT Web Application project if that is useful.
Here's the exact error I'm seeing
[ERROR] [draganddroptree] - Errors in 'jar:file:/C:/Documents%20and%20Settings/E18538/workspace/DragAndDropTree/war/WEB-INF/lib/gquery-dnd-bundle-1.0.4.jar!/gwtquery/plugins/droppable/client/gwt/DragAndDropCellTree.java'
[ERROR] [draganddroptree] - Line 24: The type com.google.gwt.user.cellview.client.CellTreeNodeView is not visible
[ERROR] [draganddroptree] - Line 86: CellTreeNodeView cannot be resolved to a type
[ERROR] [draganddroptree] - Line 87: The constructor DragAndDropCellTreeNodeView<T>(DragAndDropCellTree, CellTreeNodeView<?>, TreeViewModel.NodeInfo<T>, Element, T) refers to the missing type CellTreeNodeView
[ERROR] [draganddroptree] - Unable to load module entry point class com.cme.draganddroptree.client.DragAndDropTree (see associated exception for details)
[ERROR] [draganddroptree] - Failed to load module 'draganddroptree' from user agent 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1' at localhost:4490

You cannot arrange the loading of your "WEB-INF/lib" JAR's in any kind of deterministic order. The only surefire workaround I can think of is to place the lower-priority JAR file in a directory that is scanned prior to "WEB-INF/lib".
For example, if you are using Tomcat, then you could:
Place the "gwt-servlet.jar" file in the "$CATALINA_BASE/lib" directory.
Keep the "gquery-dnd-bundle-1.0.4.jar" file inside your WAR.
This way, "gwt-servlet.jar" will be loaded into the CLASSPATH first, and "gquery-dnd-bundle-1.0.4.jar" will be loaded second... overwriting any conflicting classes from "gwt-servlet.jar".
If you are using some other app server, then the server-level "lib" directory will be different... but the basic idea is that the lower-priority JAR needs to go into the app server's "lib", while the higher-priority JAR needs to stay in the webapp's "lib".
Not the cleanest situation in the world, but it will guarantee the result you want.
UPDATE: You know, after thinking about it and re-reading the Tomcat docs more carefully, I may actually have this backward. You may need to put "gquery-dnd-bundle-1.0.4.jar" in your app server "lib", and "gwt-servlet.jar" in your webapp's "lib". If you try my suggestion and find that it works for you with one approach over the other, let me know and I'll edit my answer to be more precise.

To solve this bug you should have gquery-dnd-bundle-1.0.4.jar set before GWT in your classpath. Using Eclipse in your project properties go to Java Build Path / Order an export and make sure gquery lib is before GWT.
Anyway you may have another problem as gquery-dnd-bundle-1.0.4.jar is compatible with GWT 2.3.x and you are using GWT 2.4. Until a new release of dnd-bundle you can use the enhance-plugin-1.0.2.jar (contains the DND bundle) and gwtquery-1.1.0-SNAPSHOT.jar.
You should look also at the native drag and drop support added in GWT 2.4. Documentation is scarce, but I found this example (you can drag templates from the right and drop them in the task details), and the relevant source code. (info from this post)

Related

Properties in manifest

IBM Cognos generates EAR file which includes a lot of JARs in /WEB-INF/lib/
Of those JARs, a few (namely, idvisualizations_helpers.jar and some others) in their /META-INF/MANIFEST.MF contain the following:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: jvmwi3260sr10-20111207_96808 (IBM Corporation)
Main-Class: ${project.main.class}
Class-Path: ${relative.classpath}
Is this valid? I mean, who will be responsible for expanding those {} placeholders? To me this does not even make any sense: if software executing the JAR knows its main class, there is no reason to mention it in Manifest.
I can only think of two explanations. First, this is a plain and simple bug, a failure to substitute those placeholders when making a JAR. Second, such a notation is valid and assumes that the JVM using that JAR will provide values for those placeholders (but I don't believe in this, as specifying different value for each such JAR would be too inconvenient).
Someone please explain what does that mean. More practical part of the problem is that on Websphere Liberty 8.5.5 an error is produced because of "${relative.classpath}" not being a valid URI. I wonder why that does not happen on another environment running full Websphere (though the Cognos configuration there differs from mine).
No, having properties in your final manifest that is used by the Java JVM is not valid based on the Java specifications. When I say "final" I mean you might have properties in your manifest as part of your source code which are then filtered out during the build and replaced with the values of those properties. This is perfectly fine. Another possibility is that there may some post-build processing that replaces those properties with the correct values.
You said:
...on Websphere Liberty 8.5.5 an error is produced because of "${relative.classpath}" not being a valid URI. I wonder why that does not happen on another environment running full Websphere (though the Cognos configuration there differs from mine).
I'm not quite clear on what you meant with that last part about the Cognos configuration differing from yours, but it sounds like you're saying that the manifest you showed in your question is working on one platform but not on another. I would imagine that either one platform is performing post processing or the two platforms have different deployed code somehow. I suggest going back and confirming that you have the exact same manifest in both platforms and debug your build process to try to find where those variables' values are obtained and when.
Please see this link for more information about the manifest file.

attract attributes typing java plugin for rhapsody

I need to write a java plugin will draw on the attributes using the rhapsody . What do you recommend for that. Where should I start ? Previously I did not write plug-ins.
First place to start is to look at the samples provided by IBM. You can find them (on Windows 7, version 7.5.3 of Rhapsody) in:
C:\Users\\IBM\Rational\Rhapsody\7.5.3\Samples\ExtensibilitySamples
There are 3 types you can create:
1. A plugin (what you are asking about)
2. A Check plugin (ties into the model check sub-system)
3. Event callback plugin (don't know much about this one)
I've written 1 and 2.
There should be a how-to document in and around that directory area that walks you through creating a simple plugin. If not, it probably is available in the Rhapsody help (from within the tool)
Basically, you write your Java plugin to conform to a specific interface that IBM provides(com.telelogic.rhapsody.core.RPUserPlugin), create a .hep file that describes the details of that, and then drop the .hep file into the .rpy folder of your project. You then create a new profile in your model with the same name as your .hep file and that should link to the .hep information.
A sample .hep file looks like this:
[Helpers]
numberOfElements=1
#REM: Tranformer Generation plug-in
name1=Generate Transformers
JavaMainClass1=sida.jni.transformerplugin.TransformerPlugin
JavaClassPath1=..\TransformerPlugin\DefaultConfig
isPlugin1=1
isVisible1=1
DLLServerCompatible1=1
Take special note of the numbers added to the end of the attribute names:
ex. isPlugin1, isVisible1
You will want to match that to the name# attribute in the file.
Then make sure your java plugin class files are on the classpath or (better yet), co-located to your .rpy folder. For example, our plugins sit in a folder right next to (at the same level as) our .rpy folder.
If all goes well, you should see an initialization string spit out in the Rhapsody console window for the plugin.
Hope this gets you started...

Compiling standalone selenium: Failed to load Main-Class manifest attribute from

I'm a total Java noob so please understand =) I need a quick advice on how to fix the issue.
I cloned the official selenium git repo, changed the code a bit (need to dump the page into some specified dirs), and tried to rebuilt it:
./go //java/server/src/org/openqa/selenium/remote/server:server:uber //java/client/src/org/openqa/selenium:client-combined:uber
It was successful but when I tried to execute it I got this:
$ java -jar build/java/server/src/org/openqa/selenium/remote/server/server-standalone.jar
Failed to load Main-Class manifest attribute from
build/java/server/src/org/openqa/selenium/remote/server/server-standalone.jar
Tried to check classpath, CLASS_PATH and CLASSPATH env variables (as a friend of mine suggested) - I simply don't have any.
At the same time, the pre-compiled standalone server from the official downloads works out of the box.
The official docs didn't help. There's nothing about it there.
So - I need a quick advice how to compile it? Thanks.
P.S. JDK 8 (latest), Mac OS 10.7
P.P.S. That friend of mine tried to build it by himself and he was lucky - he got a new build/dist folder where the target big file was. But in my case, the build folder is created, but there's not 'dist' folder in it.
Finally found the answer: I should have built it like that:
./go clean release
it's really strange that all the docs state I need to use these long /bla/bla/:uber things to get a whole single 'uber' server.

org.apache.axiom.om.util.AXIOMUtil cannot be resolved

I'm trying to generate some stubs for a WSDL (using xmlbeans) and keep running into some issues. I'm using the following page:
http://axis.apache.org/axis2/java/core/docs/userguide-creatingclients-xmlbeans.html
The only part of these steps that I'm skipping is the "client.java" part because I already have another project ready I want to plug the resulting jars into. A quick run down of my steps are as follows:
My WSDL is a crmonline instance, so I run something like this:
C:\Work\aaa2>WSDL2Java -uri
https://mycrmorgname.crm.dynamics.com/XRMServices/2011/Organization.svc?wsdl
-p crmsdk -d xmlbeans -s -o c:\mystubfolder
I build the project using "ant"
In my "client" project I reference the 2 jars created in .\build\lib
My project builds fine once I add all my axis2 / apache references etc, but when I launch it through playframework I get errors when I hit the first page. The first error seems to be:
17:48:45,289 ERROR ~ Error in ControllersEnhancer.
controllers.ProfileController.editProfile has not been properly enhanced
(fieldAccess javassist.expr.FieldAccess#212ca458).
or something similar to that. Scrolling down through the error I can see that I'm getting this:
The file /app/models/MyDynamicsClient.java could not be compiled.
Error raised is : org.apache.axiom.om.util.AXIOMUtil cannot be resolved
Now, I haven't even hit any of my web services yet, or even instantiated any of my classes ... I'm at a loss as to why this is happening. Or to be more accurate, what exactly am I messing up! Am I missing a reference to something? Doing a search on AXIOMUtil tells me this should be in Axiom-api (version I have is Axiom-api-1.2.10.jar). I have this referenced and doesn't seem to help. Or maybe I'm doing something else wrong someplace?
Some details on versions:
Axis2 1.5.4
Apache-ant 1.8.3
Any help would be very much appreciated!!
Ok, after trying a lot of different things and rereading the sites/instructions I realised what I was doing wrong. Or at least I figured out a couple of things that I started to do differently that fixed the problem.
Firstly, I was using jar files from another sample project for the apache http components. I don't know if this had an impact, but I downloaded a fresh version of this anyway and referenced those JARS instead.
Also, instead of creating jars in my "stub" project and referencing those I copied all the generated stubs/classes directly into the existing client project. I have a feeling this might have been what fixed my problem. Or maybe a mix of this and the previous step I did!
So my new steps are as follows:
Ensure you have all the correct versions downloaded for required components. In my case I have the following:
Apache Axis 2 v 1.5.4
Apache HTTP components client 4.1.3
Apache-ant 1.8.3
Copy all the JARS from the Axis2 and HTTP Components libs into your client project and reference them.
Use WSDL2Java to create your stubs and classes within it's own project.
Ensure the project builds using Ant
Copy all the generated class files within the src folder into the source folder of your client.
Fix any other reference isssues and Build
Thankfully this got me going.

How to track down JAR with corrupt JAR Index that cause InvalidJarIndexException in Tomcat in Eclipse

I am working with development of an application which, among other pieces of code, contains a number of servlets. The development environment I use is Eclipse (3.2.1, which is rather old) in which I run a Tomcat server (5.5.23, rather old as well) using the Eclipse Tomcat Wrapper plug-in for the task. All this runs on a RedHat 5.2 Linux system.
The Java runtime I use is JDK 1.6.0(21), which I upgraded to (from a previous JDK 1.5 version) quite recently and as far as I can recall, the software combination above (together with the application I'm working with) did actually work: I could start the Tomcat server, it got up without errors or complaints and the application's servlets were available on port 8080.
However, something has changed somewhere (could be in the application jarfiles themselves, I'm suspicious of essentially everything on the host to be the root cause of this). Now, when I try to start up the Tomcat server, I get the error sun.misc.InvalidJarIndexException in the console output. This happens for the following classes and methods:
org.apache.commons.modeler.Registry registerComponent (happens 3 times)
org.apache.catalina.core.StandardServer initialize (happens once)
org.apache.catalina.connector.Connector start (happens twice)
I did find this stack overflow question regarding how to find the JAR of a Java Class useful and I did run find /usr -name \*name-of-suspected-jar\*.jar a few times to track down a number of suggested offending JARS. I also tried to check the runtime configuration of the Tomcat server in Eclipse, but could really not match the JAR files on the system with the CLASSPATH of neither the Tomcat runtime setup (or with the CLASSPATH used in the environment when starting Eclipse). That effort probably requires some more rigor on my part but before doing that (and that is why I right now don't post all the gory details regarding CLASSPATHs here), I did a read up on exactly what InvalidJarIndexException really is about.
So, JAR files may contain an optional INDEX.LIST file which contains information about what classes (and methods?) to find in the JAR file. The idea is to short-circuit the search throughout all JARS in the CLASSPATH which is useful in a number of circumstances. Problem is when the INDEX.LIST file happens to be corrupt (or, is believed to be corrupt), that causes the loading of the class to be completely given up (the class loader does not fall back to searching all JARs in the CLASSPATH) and the error InvalidJarIndexException to be thrown. To make things more messy, the order in which JARs are searched might affect how the class loader treats the INDEX.LIST file: the INDEX.LIST file of one JAR might refer to other JARS and if those referred to JARS are not in sync with the first JAR's INDEX.LIST file, the class loader fails with this InvalidJarIndexException error.
So (according to this StackOverflow question), it seems like this error can be thrown not only because a JAR file has a corrupt INDEX.LIST, it seems it can even be thrown on a JAR even if the JAR has a valid INDEX.LIST or legitimately is lacking a INDEX.LIST simply because a previously searched JAR has confused the class loader. (To put in another way, as things are, this exception might be thrown even for "innocent" non-corrupted JAR files due to offenders elsewhere on the system).
So, after writing a mere novel, here comes my main set of questions:
What is the best way to track down the precise .jar file for which each InvalidJarIndexException is thrown?
What is the best way check if a randomly picked .jar file has an INDEX.LIST file and if so, if said file is valid (that is, non-corrupt)? What tools exist for this task?
Is there an efficient way to automatically deduce the search order of .jar files? I can try to follow the CLASSPATH manually but to be honest, that is error prone and tedious.
Is there an efficient way to figure out what .jar file there is in a search order which might confuse the class loader to accuse innocent, non-corrupt .jar files later in the search to have incorrect INDEX.LIST files?
Disclaimer: I know I run old versions software (even if I have the latest updates of my Redhat 5.2 installed though) and I know a knee-jerk reaction for many people is to suggest that I don't put any effort whatsoever in debugging this but instead upgrade to a more recent version of Tomcat, Eclipse and Linux (Java is recent though). The reason I would prefer not to is that after looking into things, I've found it rather messy to do an upgrade or to try to install a separate modern Tomcat or Eclipse next to the RHEL5.2 provided Tomcat/Eclipse I use today. Also, I consider this kind of troubleshooting an opportunity to learn some useful nitty gritty details about Java and it's associated tools and features. Figuring out how the class loading works and what causes it to throw this InvalidJarIndexException on my system would be very educating!
(But if this troubleshooting fails, I'll seriously consider to use a modern Linux, Eclipse and Tomcat... I promise)
Take the following steps to diagnose the problem:
Add an exception breakpoint in Eclipse (it's the J with an
exclamation mark icon), and set it to halt for caught and uncaught
exceptions, of type InvalidJarIndexException.
Start debugging your program.
Eclipse will halt at your exception breakpoint, when the InvalidJarIndexException is thrown. Even without the source for URLClassPath, you will still be able to inspect the variables on the stack leading to the exception, including the name of the class that URLClassPath is attempting to locate. Knowing the name of the class should significantly narrow the list of JAR's you need to examine.
Perhaps you've locally added a new class to a package and the contents of that package are described by the index file in a stale JAR on your classpath?
Try Tattletale which is a good reporting tool for jars. What I have done in this case was to eliminate INDEX.LIST from jars one by one until I did not get InvalidJarIndexException any more

Categories