Manifest.mf Class-path trouble

Discussion in 'Java' started by Lukas, Nov 24, 2005.

  1. Lukas

    Lukas Guest

    Hi group!

    I'm deploying an application with this structure

    app
    app/app.bat
    app/lib/app.jar
    app/lib/another.jar
    app/plugins/other/

    where the (windows) batch file starts the application like so:
    java -jar lib\app.jar

    and the Manifest.mf with that jar puts another jar on the classpath
    like so:
    Class-Path: another.jar

    Now I also want to put any plugin classes that users put into
    app/plugins/other/ onto the classpath, roughly like so:
    Class-Path: another.jar "../plugins/other/*"

    So far I've tried a few variations, but the development cycle is quite
    tedious and it ain't workin yet.
    I'm wondering:

    * use quotes ?
    * forward slashes ok on windows or do I need separate versions for Win
    vs Unix ?
    * end the directory with / (or resp. \) or nothing (../plugins/other) ?
    * end the directory with "/*" or possibly "/*.class" ?

    Alternatively I could use the java -classpath arg in the batch file,
    but I've tried that and it's not working either, so I'm getting the
    impression that using the Class-path: line in the manifest somehow
    disables the -classpath arg of the java command. Is that so?

    YT
     
    Lukas, Nov 24, 2005
    #1
    1. Advertisements

  2. Lukas

    Dave Glasser Guest

    The classpath segments can only be paths (relative or absolute) to
    directories or jar/zip files. Wildcards won't work.
    It disables the -classpath arg only if the program is started with the
    java -jar jarfile.jar command.

    If your app uses user-supplied plugins, then I think your best
    approach is a custom classloader that will monitor the plugins
    directory. Here's an example of one I use for JDBC drivers:

    http://cvs.sourceforge.net/viewcvs....ExtensionClassLoader.java?rev=1.2&view=markup

    A user can put JDBC driver jar files into a "drivers" directory, and
    they'll be available at runtime. This example doesn't re-read the
    drivers directory at runtime, so you have to restart when you add a
    jar. It would be trivial to make it rescan the directory, however.




    --
    Check out QueryForm, a free, open source, Java/Swing-based
    front end for relational databases.

    http://qform.sourceforge.net

    If you're a musician, check out RPitch Relative Pitch
    Ear Training Software.

    http://rpitch.sourceforge.net
     
    Dave Glasser, Nov 24, 2005
    #2
    1. Advertisements

  3. The Class-Path has to be relative to the current working directory (app/)
    and not relative to the app.jar file (app/lib/). So the correct entry would
    be

    Class-Path: lib/another.jar
    To add the root-folder for plugin-classes just use

    Class-Path: lib/another.jar plugins/other

    then you have to build the package-structure below this folder as subdirs.
    But this is not the standard way to include plugins.
    Normally you use a Class-Loader (like URLClassLoader) to load some libs at
    runtime.
    forward slashes are ok for all OS in java.
    yes


    Best regards,

    feri
     
    Ferenc Hechler, Nov 24, 2005
    #3
  4. Lukas

    Dave Glasser Guest

    That's not correct. According to this page:

    http://java.sun.com/developer/Books/javaprogramming/JAR/basics/manifest.html

    "The URLs in the Class-Path header are given relative to the URL of
    the JAR file of the applet or application."


    --
    Check out QueryForm, a free, open source, Java/Swing-based
    front end for relational databases.

    http://qform.sourceforge.net

    If you're a musician, check out RPitch Relative Pitch
    Ear Training Software.

    http://rpitch.sourceforge.net
     
    Dave Glasser, Nov 24, 2005
    #4
  5. Lukas

    Lukas Guest

    and the Manifest.mf with that jar puts another jar on the classpath
    That can't be true: the "Class-Path: another.jar" is definitely
    working.
    Also, the docs seemed to indicate that the path has to be relative from
    the jar.
     
    Lukas, Nov 25, 2005
    #5
  6. Lukas

    Lukas Guest

    I've now tried various combinations, none of which work:

    * Class-Path: another.jar ../plugins/other (my favorite candidate)
    ... the classes from another.jar are found, but not those within
    .../plugins/other

    * Class-Path: another.jar ..\plugins\other (backslashes for win)
    ... ditto

    * Class-Path: lib/another.jar plugins/other (from working directory)
    ... the classes from another.jar aren't found, as I would've expected

    It's clear that the relative path is interpreted from the location of
    Jar file that has the manifest, which also should be the case according
    to the docs.
    I'm getting the impresssion that the convention "up one level" :
    "../" doesn't work here.
    Could that be the case?

    I'm using a classloader for a different type of plugin, but for these
    plugins here (where naming conflicts are not expected) having the
    plugin directory on the path is sufficient. The approach is fine,I've
    got it working in Eclipse, I just have to get it to work in the
    installed directory as well.
     
    Lukas, Nov 25, 2005
    #6
  7. Lukas

    pkriens Guest

    If you have such a plugin problem, take a look at the OSGi
    specifications. Eclipse uses these specifications to model their plugin
    model, as well as the Apache Directory server and thousands of
    commercial applications. It is lightweight and saves you many debugging
    hours. You can download OSGi frameworks from Eclipse, Oscar/Felix
    (Apache), and Knopflerfish.

    See http://www.aqute.biz/osgi.html for more info.

    Kind regards,
    Peter Kriens
    OSGi Evangelist
     
    pkriens, Nov 25, 2005
    #7
  8. Lukas

    Lukas Guest

    I don't have a plugin problem.
    Period.
    All I need to achieve here is to get a directory on the classpath from
    a JAR's manifest.
    Please stay on target folks.
    Just like regular folks, Evangelists should read the actual thread
    before starting to spam.
     
    Lukas, Nov 25, 2005
    #8
  9. Lukas

    Lukas Guest

    Hi group,

    I set up a test project to get some clarity on the issue:

    app/
    app/needy.jar
    app/org/anorg/aproject/NeedyClass.class
    app/adirectory/org/another/NeededClass.class

    where NeedyClass has the main() method and needs NeededClass to
    execute, as you would expect.

    The internal structure of needy.jar is:

    org/anorg/aproject/NeedyClass.class
    meta-inf/Manifest.mf

    The working directory is app:

    While

    java -cp adirectory;. org.anorg.aproject.NeedyClass

    exectutes properly (on Windows),

    java -cp adirectory org.anorg.aproject.NeedyClass

    does not (NoClassDefFoundError: org/another/NeededClass).
    Why the working directory has to be on the classpath in this case
    puzzles me.
    Anyway, so far so good.

    However, when combining the java -cp option with executing the same
    NeedyClass inside the jar, something appears to block the -cp option.
    For this experiment, the Manifest only defines the main-class and has
    no Class-Path line:

    java -cp adirectory;. -jar needy.jar

    fails with NoClassDefFoundError: org/another/NeededClass

    It seems safe to conclude that the -jar option blocks the -cp option.

    Moving the reference to adirectory into the Manifest like so:

    Class-Path: adirectory .

    (note that the dot above is the reference to the working directory,
    same as with the java -cp option)
    or:

    Class-Path: adirectory

    ... fails with the usual error.

    The Sun documentation on the Class-Path attribute in Manifest files is
    a bit fuzzy on this point -- while it describes the syntax for listing
    multiple JARs and JARs within directories, there is no explicit mention
    of listing just a directory (for access to all *.class files within).

    All this seems to indicate that, when invoking with "java -jar" , there
    is no way to get classes that have not been jarred onto the classpath
    (Setting an environment variable remains an option, but for deployment
    I'd rather avoid that).
    Fairly shocking.

    Can anyone confirm this?

    YT
     
    Lukas, Nov 28, 2005
    #9
  10. Lukas

    Roedy Green Guest

    When you use a jar, it is considered a feature that the classpath and
    -classpath option on the command line is ignored without comment.
    Everything has to be specified in the jar's internal Class-Path. It
    accepts only relative path names, and I have heard reports that ../ is
    not supported in the names.
     
    Roedy Green, Nov 28, 2005
    #10
  11. Lukas

    pkriens Guest

    Sorry to get confused thinking that you were rolling your own plugin
    system :-(
    You must be following Rudy's advice about naming for unmaintainable
    code ...

    Have tried to use Class-path in the past and found it to be utterly
    useless,
    and OSGi framework make what you try to do trivial (which
    it is not with raw class loaders).

    Kind regards,

    Peter Kriens
     
    pkriens, Nov 29, 2005
    #11
  12. Lukas

    nakshathri

    Joined:
    May 6, 2008
    Messages:
    1
    Likes Received:
    0
    Hi Team,

    Even i have the same problem with the Class-Path inside the manifest file.

    It seems like ../ will work fine in the classpath. but its actually giving a warning message in the log file saying that "is illegal according to the Java Extension Mechanism: must be relative and not move up directories ". :-(

    I have to move up the directories to include the Plugin library jar which i have.

    Is there any other way to specify the classpath without moving up the directories(Note: I cant change the folder location. So is there any relative path mechanism for this?????????????)
     
    nakshathri, May 6, 2008
    #12
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.