Class Path

Set depended jar libraries in classpath


Introduction

Your java program may need other jar libraries when it runs. Jar2Exe supports to pack depended jar files into exe file, those embedded jar files are included in classpath already. For jar files outside of generated exe file, it is supported to set 'class path' by many ways:

  • From environments CLASS_PATH and CLASSPATH
  • From a configure item 'classpath' in configuration file to specify one or more 'jar files'
  • From a configure item 'libs' in configuration file to specify a 'directory' which contains jar files

Environments CLASS_PATH and CLASSPATH

Generated exe will add jar libraries in environments CLASS_PATH and CLASSPATH into java classpath.

If you don't want your generated exe to use jar libraries in environments CLASS_PATH and CLASSPATH, you can use a 'export' configure item to overwrite the environments.

  • See export page for how to set environments.

Configure Item 'classpath'

You can use a configure item 'classpath' in configuration file to declare depended jar libraries.

Configure item 'classpath' should be followed by a path to jar file, or a directory which contains ".class" files.


Configure Item 'libs'

If you have too many jar files to add to classpath, you can use configure item 'libs' instead of 'classpath'.

Configure item 'libs' points to a directory, and generated exe will add all jar files in the directory to classpath, while if 'classpath' points to a directory, it means to add the directory itself to classpath.

 

Comments

Resources in embedded jar file not found

I have restructured my project to seperate functions into different jar files (I'm using Maven Master project)

However now, when I build with Jar2Exe my sub-jar file now can't locate resources within the jar (I'm using Google Flyway to perform database migration on SQL files in resource folder)

My code within the jar file

URL resource = Thread.currentThread().getContextClassLoader().getResource(dataload[0]);
if (resource != null)  {
    File resFile = URLHelper.asFile(resource);
    System.out.println("RESOURCE FILE ["+dataload[0]+"] found["+resFile.exists()+"]");                   

}
else {
    System.out.println("RESOURCE URL returned ["+(resource != null ? resource.toString() : "is null")+"]");                   

}

Now returns

RESOURCE URL returned was [is null]

 

From what I have read elsewhere on this forum I am using the correct ClassLoader - Thread.currentThread().getContextClassLoader().

I am building this via J2EWIZ with the following

J2EWIZ MyApplication.jar ^

...

/embed lib\MyDBUtility.jar ^

...

/config "classpath lib\bcprov-jdk15on-1.51.jar" ^

 

And I have tried adding as "/config "classpath..." (as above for Bouncy Castle jars) but that gives a class not found - and anyway I'm not keen on have this jar external to the executable.

Hoping you can help.

Thanks

David

I have dug a bit more on this

I have dug a bit more on this - my original checking code was wrong

The problem (I think) is that the J2E classloader doesn't seem to recognise a "folder" as a resource.

String checkFile = "database_migration/V1__my_db.sql";    // specific SQL file
System.out.println("Datafile ["+checkFile+"]");
URL resource = Thread.currentThread().getContextClassLoader().getResource(checkFile);
if (resource != null) {
    System.out.println("RESOURCE FILE ["+checkFile+"] URL["+resource.toExternalForm()+"]");   
}
else {
    System.out.println("RESOURCE URL returned ["+(resource != null ? resource.toString() : "is null")+"]");                   
}

 

Returns (I note the j2e: reference in URL)

 

RESOURCE FILE [database_migration/V1__my_db.sql] URL[j2e:libs/MyDBUtiliity.jar!database_migration/V1__my_db.sql]

However with just a folder as

String checkFile = "database_migration";    // just folder with versioned SQL files

Returns

RESOURCE URL returned [is null]

Whereas in normal java environment this returns

RESOURCE FILE [database_migration] URL[file:/C:/Users/david/dev/MyApplication/target/classes/database_migration]

My problem is that Flyway seems to only work at folder level

Flyway flyway = new Flyway();
flyway.setClassLoader(Thread.currentThread().getContextClassLoader());
flyway.setDataSource(ds);
flyway.setLocations(migrations);  // String[] with multiple folders with versioned SQL files
flyway.setCallbacks(new MyFlywayCallback());
flyway.migrate();

I'm looking for a work-around in Flyway - but wondered if you could confirm J2E ClassLoader support for folders as resource?

Edit:

Flyway is a BoxFuse product (rather than Google as I indicated above) - here is their info on Database Migrations <https://flywaydb.org/documentation/migrations#versioned-migrations>. 

I have got the option to use "filesystem:" working - rather than "classpath:",  but that would leave SQL files, which define the application database, exposed and getting the classpath approach working is my strong preference.

 

Thanks

David

 

 

 

Flyway work-around

Hi

I'm not sure if this product is supported anymore - no response here, email or Skype - that's a shame

However I managed to get Flyway working inside Jar2Exe - so updating here.

I was only able to do this by forking Flyway to add handling for "j2e" classLoader protocol.

Plus, as indicated above Jar2Exe doesn't support folders - which I understand via "getResource("database_migration")" (singular) but might have hoped that "getResources("database_migration")"  (plural) gave a file list.  Therefore I also had to add file support to Flyway as well.

I'm happy to provide Flyway code changes to anyone with same problem - but ideally Jar2Exe could be updated to support getResources on a folder.  If it did I would provide my Flyway changes to https://github.com/flyway/flyway as a pull request. 

 

 

Add new comment