Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Help with adding external JAR files

2006-12-07
2013-05-02
  • Oskar Skeide
    Oskar Skeide
    2006-12-07

    I need some help with adding libraries to our application (http://sf.net/projects/mypal). I think JPF is very nice to work with, but I've been encountering some troubles with classpaths lately. The problem started when I added a JAR file that every plugin should be able to use.

    org.mypal.core is the ApplicationPlugin, in addition to that, there are four other defined plugins. I have a JAR file, iframe.jar that all plugins should be able to use, and as a shared library it is very tempting to put that JAR file in /APPLICATION_ROOT/lib along with the rest of the JAR files.

    org.mypal.core/plugin.xml has a tag called <library>. In this tag the libraries imported by the plugin in declared. Problem is, it seems like it is not possible to declare libraries beyond the org.mypal.core directory...

    This works fine:

    <library id="iframe" path="lib/iframe.jar" type="code">
    <export prefix="*"/>
    </library>

    This doesn't work:

    <library id="iframe" path="../../lib/iframe.jar" type="code">
    <export prefix="*"/>
    </library>

    This does not work either:

    <library id="iframe" path="${basedir}/../../lib/iframe.jar" type="code">
    <export prefix="*"/>
    </library>

    org.mypal.core/build.xml contains two classpaths:

    <path id="plugin.classpath">

    <fileset dir="${basedir}/../../lib">
    <include name="*.jar" />
    </fileset>

    <fileset dir="${basedir}/lib">
    <include name="*.jar" />
    </fileset>

    </path>

    In "${basedir}/../../lib" there are JPF libraries, it seems like org.mypal.core plugin has no problems finding these libraries, even though they are not defined in org.mypal.core/plugin.xml . If I try to put other JAR files in "${basedir}/../../lib" they cannot be found; It seems like the JAR files I would like to add to the runtime libraries in plugin.xml must be placed in a directory deeper down the sourcetree than APPLICATION_ROOT/plugins/[BASEDIR]/ .

    I guess that JPF libraries doesn't need to be defined as runtime libraries because they are only used at boot-time (?).

    I have this plugin, org.mypal.email, that should also be able to use iframe.jar, so I have two questions for you:

    1)Assuming I put iframe.jar in /plugins/org.mypal.core/lib/ ; How do I make iframe.jar visible to org.mypal.email-plugin ?
    2)Assuming I put iframe.jar in /lib/ ; How do I make iframe.jar visible for the plugins ?

    I have spent a lot of time reading the documentation and these forums without finding a solution, so I am not asking just because I am lazy :)

     
    • Prashant Bhat
      Prashant Bhat
      2006-12-09

      Hi Oskar Skeide,

      You can do it with requires tag in plugin.xml. Have a look at the JPF-Demo and projects listed under Success Stories http://jpf.sourceforge.net/stories.html (like Samooha - http://samooha.sf.net\)

      If you put your jar in to the outside lib folder, then it will be available to all plugins(No need to configure anywhere else). But this approach is not suggested as it deviates from the basic module/plugins concept for which JPF is used.

      Hope this helps.
      Regards,
      Prashant.

       
      • Urs Reupke
        Urs Reupke
        2006-12-10

        Hello Oskar,
        As an alternative to Prashant's solution, you can replace the "Path Resolver" used by JPF with a custom one. I faced a similar problem and came up with the class you can view at http://fisheye3.cenqua.com/browse/anathema/trunk/Anathema/src/net/sf/anathema/AnathemaPathResolver.java?r=2073

        It parses the "library" declarations in the various plugin declaration files and replaces all occurences of the constant ${ANATHEMA_LIB} with "./lib/" before the URL is resolved, while all that lack that constant are resolved as before.

        For example, my itext declaration
        <library id="iText" path="${ANATHEMA_LIB}/itext-1.4.jar" type="code">
        <export prefix="*"/>
        </library>
        is looked at ./lib/itext-1.4.jar, where "." is the folder where your main .jar is located. The export tag allows all dependent plugins to access the library, as usual.

        To use the class, you just need to replace the constants and declare it's use in your boot.properties file like this
        org.java.plugin.PathResolver=net.sf.anathema.AnathemaPathResolver

        I hope this helps you solve your problem.
        -Urs

         
    • SkyDive971
      SkyDive971
      2006-12-12

      Urs,

      I tried your solution but I think I have yet to grasp exactly how the JPF structure would load the given class.   I am getting an error that says "java.lang.Error: failed creating path resolver instance net.sf.anathema.AnathemaPathResolver"

      So this is what I setup.

      runfolder  -- This is the folder where I start the app from.
      --lib      -- This contains, commons-logging.jar,derby.jar,iframe.jar,jpf.jar,jpf-boot.jar,jpf-tools.jar,jxp.jar,log4j.jar
      --net/sf/anathema  -- This contains your class AnathemaPathResolver.class
      --plugins 
      ----org.mypal.core  -- This contains the core plugin
      :                   -- All other plugins follow this same pattern 
      ----org.mypal.xxxx

      None of my plugin.xml reference this class.
      My boot.properties references this class directly as you suggested.
      AKA org.java.plugin.PathResolver = net.sf.anathema.AnathemaPathResolver

      My run.bat file looks like this.

      SET JAVA_HOME=c:\java\jdk1.5.0_06
      SET PATH=c:\java\jdk1.5.0_06\bin%PATH%
      java -cp .;lib/jpf.jar -jar lib/jpf-boot.jar
      REM PAUSE

      Now if I write a class called TestApp and place it in the net/sf/anathema folder and that class looks like this.

      package net.sf.anathema;
      public class TestApp {

         public static void main(String args[]){
            System.out.println("Getting apr");
            AnathemaPathResolver apr = AnathemaPathResolver();
            System.out.println("Got It");
         }
      }

      And I change my run.bat file to look like this;

      SET JAVA_HOME=c:\java\jdk1.5.0_06
      SET PATH=c:\java\jdk1.5.0_06\bin%PATH%
      java -cp .;lib/jpf.jar net.sf.anathema.TestApp
      REM PAUSE

      I get;
      Getting apr
      Got it

      Without issue.

      Any ideas would be helpful at this point.

       
      • Urs Reupke
        Urs Reupke
        2006-12-15

        SkyDive,
        I'm not sure I understand the problem either.

        Outside of my IDE (where I use the DefaultPathResolver), I run the program from a .jar, in which the boot.properties, the AnathemaPathResolver and my Bootloader (which does nothing but forward its call to JPF's Boot.main() so users can just run my .jar instead of JPF) reside, and there are no problems at all.

        The jar's classpath contains nothing but
        lib/jpf.jar lib/jpf-boot.jar lib/commons-logging-api.jar
        so things *should* work on your side as well.

        As a guess, maybe JPF can't find the class because it is not on the classpath - it's neither in jpf.jar nor in jpf-boot. But then again, I've not set a java classpath manually from console in the last 3 years, so you probably know what to put there much better than I do.