0

I am working on an application server that uses worker JVMs to do various things.

The worker jvms are started using -cp switch and specify JAR files that contain vendor libraries and other important functionality.

I have a really interesting problem where the jar files CLASSES load and execute code properly but any time they attempt to access a RESOURCE within the jar file (specifically with getResourceAsStream() method) then it blows up claiming it can't find it. I have verified that these resources are definitely there in the JARs that are being loaded and in fact if I manipulate the JAR to locate the resource externally, it works. The problem is these are all proprietary libraries and don't come with source so I'm crippled in that I have to do everything through decompiling and method entry breakpoints.

Perhaps the strangest part is these libraries have been unchanged for many months and have been working in other (including production) app servers.

They are on JRE 1.6.0_17

So my question is

  • Why would a JVM with -cp entries be able to load CLASSES from the jar but not RESOURCES
  • Does anything in this realm change from JRE 1.6.0_06 to 1.6.0_17 (this has changed recently)

To clarify, in the JAR structure these resources are on the root of the jar ie:

resource.prop
META-INF/Manifest
package/package/class.class

the JAR itself is clearly on the classpath as it is loaded. However all of the following resolve to NULL (yes this is driving me nuts so I did actually try all 3):

Jarclass.getClassLoader().getResourceAsStream("./resource.prop");
Jarclass.getClassLoader().getResourceAsStream("/resource.prop");
Jarclass.getClassLoader().getResourceAsStream("resource.prop");

This looks similar to Can't access resource in a JAR on all computers but there is no resolution to that question.

Community
  • 1
  • 1
Evan Cross
  • 31
  • 1
  • 3
  • The only thing that comes to mind is: the JAR's may use custom class loaders that rely on some odd behavior in the JRE implementation (writing a classloader is not trivial). Is the problem generally limited to libraries from one vendor? If you do Jarclass.getClassLoader().toString(), does it indicate that this is not a ClassLoader created by the JRE? – Durandal Aug 14 '12 at 17:24
  • Incredibly insightful comment predicting something I didn't even allude to in my original post. You were absolutely right that there was a custom classloader being used by one of the vendors and it was overriding the JRE standard classloader particularly for loading resources. None of MY libraries had changed but I didn't think to check for other libraries containing changed classloaders. I looked into it and found this is the problem - the vendor made a mistake in a change they made to the custom classloader. Thanks! – Evan Cross Aug 15 '12 at 18:15

2 Answers2

0

Have you examined the manifest.mf file from the JAR? That is one of the easiest, if not only, way to control the classpath used to load resources located inside a JAR.

Reading resources from a JAR is only partially related to the classpath used to load the JAR. For class files, the folder structure inside the JAR is sufficent for the classloader to load the classes, basically [CLASSPATH]/[Package]/[Classname].

For resources it is a different matter. The root of the JAR is added to the CLASSPATH but not any child directory, so if "resource.prop" is in the root of the jar, any of the three examples you provided would work. Since you said they are already in the root of the jar, it only deepens the mystery.

Did the JAR change somehow, like an older version worked and the new one doesn't?

Have the CLASSPATH settings for your app server changed recently? We ran into a problem with IBM's WebSphere Application Server where we had to set the rule for classloaders to 'parent last' (at least if my memory doesn't fail me here) so that it would use the Classpath from the JVM instance first and then use the classloader for WebSphere because we loaded a log4j.jar that was older than the one IBM started including in a newer version of WebSphere.

Another option would be to expand the JAR, update the manifest.mf file to include absolute references to the properties, then re-jar the files into a custom version.

Kelly S. French
  • 12,198
  • 10
  • 63
  • 93
0

Check names of dirs in which non-working jars placed. I had similar problem when my app was copied to dir with symbol ! or % in its name.

Nestor
  • 756
  • 4
  • 8