Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Ant: Compile time vs runtime classpath

 
John R Roberts
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, I wrote a little demo app that has a Session Bean and a client to call the Bean.
My buils script is used to compile and jar the code and this works fine.
When I call my Run target I get a NoClassDefFoundError, (cant find the Jboss j2ee jar file).
Why is this??

here is some code from the build script.


in the lib folder are the required J2EE jar files



code compiles fine here



when I call this target I get



So it appears that the jar file I am executing cannot find the required libraries. Why would this be, the compile task finds them.

any ideas???
 
Christophe Verré
Sheriff
Posts: 14691
16
Eclipse IDE Ubuntu VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think that it comes from the fact that when you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored. Refer to the Ant Manual about the java task and "JAR file execution". It's not an Ant limitation, it's the way Java works.

I can think of two "solutions", but there may be others :
1. Declare the dependencies in the Class-Path element of the manifest file
2. Don't jar the client application !
[ May 28, 2007: Message edited by: Satou kurinosuke ]
 
John R Roberts
Ranch Hand
Posts: 36
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
thanks for the reply!
 
Tim Holloway
Saloon Keeper
Pie
Posts: 18226
53
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's true. This is equivalent to the

java -jar myjar.jar

command. Which takes as its classpath the jar itself, but no embedded jar or class directories. This has often been an annoyance to people who write self-executing jars that use third-party JDBC drivers.

The quick and ugly solution would be to use a standard classpath:

java -classpath ./myjar.jar:/here/there/myjdbcdriver.jar com.bar.foo.MyMainClass

An alternative is to augment the standard classloader features of the java runtime with classloading code of your own. For example:

java -jar myjar.jar -Dmydbdriver=/here/there/myjdbcdriver.jar

Or something like that (say, getting the database driver location from a config file). To make that work, you'd then write classloading code that went out and got the external classes and loaded them.

It's not that difficult to write augmentations for classloading, but it's not a "fresher" job, either. For simple EJB client testing, you're better off not attempting to use the app jar as a self-executable jar and provide an explicit classpath. The fancier stuff is for when you want to provide a commercial-grade product that's easier for other people to use.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic