• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Classpath problems - java.class.path when using Manifest.mf

 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello all, first post here so please forgive me if I'm not posting in the right place. I'm also not an english native speaker :roll:

Anyway, I've got this little app where I need to support plugins; the objective here is that a programmer can implement an interface and simply add the class to the classpath, and the app will load it.

The way I'm currently doing is, right after starting, querying System.getProperty("java.class.path") and searching for all classes there that implement this interface I want:



The ClassFinder class can be found here (please note that I'm not the author, and simply copied it from somewhere to my project's svn).

If I run the app from inside eclipse, everything works just fine - all the classes are found and can be used. If, however, I use ant to pack them (they are packed in several different .jar files), nothing is returned.

One thing I noticed when debugging is that running inside eclipse java.class.path returns the current (correct) classpath; however, if I get java.class.path when packed, it returns only the name of the launched jar (f2s-main.jar, in this case). Shouldn't it return everything that is set in the MANIFEST.MF Class-Path attribute? I do think that is set correctly because I can use other classes from these packages in the code.
 
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Don't know, but this sounds more complicated than the average beginner's question. Moving.

And welcome to JavaRanch
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You could try reading the Manifest using java.util.jar.Manifest:

You can use getMainAttributes and getEntries to find the value.

There is one problem though: resource /META-INF/MANIFEST.MF can quite well point to the manifest file of another JAR file if that is loaded first! For example, a JAR file in the /lib/ext folder of the JRE.

I'm still working on a way to get access to the right manifest file.
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Right, I've got a basic implementation:

How this works:
- get a resource to the class file itself (only works for sure with the system class loader and URL class loader)
- strip off the part leading to the class; what remains is the root for this JAR file
- add META-INF/MANIFEST.MF
- create a new URL and open a stream to it
For example, this URL becomes
The rest is pretty much the same.


Now this code lacks a lot of stability; if the class is not run from a JAR file it will fail miserable when opening the stream because the URL does not exist. Also, the exception handling is not handled at all. But I'm sure you can figure out how to handle this.
 
Marcelo Schneider
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rob's implementation worked perfectly. The only "but" is that I need to know the class at runtime, so I passed a String argument and used:

My modifications to ClassFinder (the original Burt Beckwith/Michael Stover class for Jakarta Jmeter) can be found here.

Thank you all!
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Marcelo Schneider wrote:Rob's implementation worked perfectly. The only "but" is that I need to know the class at runtime, so I passed a String argument and used:


And that's of course the right way to go ;) Although technically you should check the result of lastIndexOf against -1 in case it's a class in the default package.

You of course do something similar with the removal part:
 
Marcelo Schneider
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry to bring this topic back up, but any ideas if I want to run it from Java Web Start? I mean, it renames all downloaded jars, so the whole "java.class.path" or manifest approach is quite useless...
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That idea you originally had keeps falling on its face every time you try it in a new environment, doesn't it? To me that means it wasn't a very good idea.

A typical way to support plugins is that the plugin consists of a manifest file which lists the plugin classes, plus the classes themselves. Then to load them you first get the manifest, and then load all the classes which it lists. A lot easier than trying to search the entire classpath.
reply
    Bookmark Topic Watch Topic
  • New Topic