GeeCON Prague 2014*
The moose likes Java in General and the fly likes Dynamically setting classpath from java Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Java in General
Bookmark "Dynamically setting classpath from java" Watch "Dynamically setting classpath from java" New topic
Author

Dynamically setting classpath from java

bob morkos
Ranch Hand

Joined: Oct 06, 2003
Posts: 56
I have an ear that I deploy which contains a property that has the classpath for which to use. Anyways, I was wondering if in my java, I could dynamically setClasspath(String path). Could anyone help, thanks in advance. I must find a way to set dynamically the classpath in my java code.
Raj Chila
Ranch Hand

Joined: Mar 18, 2004
Posts: 128

hi,

It would be impossible to compile classes which refer to some libraries which are not existing in the classpath. but here is some thing you can do.

1. use reflection...to call methods of the required class, so that you dont you just need to keep the required class path library in a place where the JVM would normally look up the classes from. the disadvantage is that you will have to depend heavily on reflection.

2. A more standard approach would be to define some interface that your application needs, and let the application that need to be integrated implement this interface. so you can limit using reflection to creating that interface ( On the lines of the Abstract Factory pattern) .

JDBC is a good example of this, you do your programming using the interfaces like connection, Statement, Resultset and some datatypes, which will take care of the compilation, and you depend on reflection only while creating the Driver through class.forName.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

You can't "set the classpath" in general, because there's no one single class path. Every ClassLoader has its own idea of how to load classes and where to find them. In an app server there are generally many class loaders in operation.

What you can do is create your own ClassLoader which knows where you want to find classes, and use it to loaded the classes of interest. The class java.net.URLClassLoader is a standard class loader that lets you hand it a class path to use -- you may be able to simply use that.

Anybody just starting out with classloaders would do well to study the papers of the great sage Ted Neward.

You need to be careful, though, because you don't want to confuse the appserver. Furthermore, the appserver may prohibit this via Java's security mechanisms.


[Jess in Action][AskingGoodQuestions]
bob morkos
Ranch Hand

Joined: Oct 06, 2003
Posts: 56
My problem is that I have 2 ears as the following 'A.ear' and 'B.ear' they both use the same datasource.xml file but the implementation is different for each one of them. So, If I put it in the server classpath it would be able to load the right one. So, the requirements is to externalize the properties and xml files to the server.

A.ear would load the CLASSPATH > %SERVER_APP_SERVER%/conf/a/xml/* (eg: datasource.xml)

B.ear would load the CLASSPATH > %SERVER_APP_SERVER%/conf/b/xml/* (eg: datasource.xml)

The way, I want to go about it is by place within each ear a config.property
which has the classpath to set. What I need is to find a way to do it dynamically in Java like:

XXX.setClassPath(c c4j/j2ee/home/conf/b/xml/dataSource.xml);

How can I do this in Java, could you show me with some code or direct me in some way. Any help would be greatly appreciated.



Originally posted by Ernest Friedman-Hill:
You can't "set the classpath" in general, because there's no one single class path. Every ClassLoader has its own idea of how to load classes and where to find them. In an app server there are generally many class loaders in operation.

What you can do is create your own ClassLoader which knows where you want to find classes, and use it to loaded the classes of interest. The class java.net.URLClassLoader is a standard class loader that lets you hand it a class path to use -- you may be able to simply use that.

Anybody just starting out with classloaders would do well to study the papers of the great sage Ted Neward.

You need to be careful, though, because you don't want to confuse the appserver. Furthermore, the appserver may prohibit this via Java's security mechanisms.
Maulin Vasavada
Ranch Hand

Joined: Nov 04, 2001
Posts: 1871
Hi Bob,

I didn't understand the following,
use the same datasource.xml file but the implementation is different for each one of them.

To me it looks like, you have TWO datasource files having different "content". XML DTD may be same for the files but the content is different. Is that what you have? If that is the case then I wouldn't put it as "Two EARs use the same file..." OR I didn't understand when you said "different implementations of the same file". How one can have "implementations" of the file??

Now, saying that, one way would be to just put those files in respective packages directory and getResourceAsStream() things would work for you to get the correct file as it would look for in the package first...

Please correct me if I am wrong.

Regards
Maulin
bob morkos
Ranch Hand

Joined: Oct 06, 2003
Posts: 56
Yes, I have TWO datasource files having different "content". But, I cannot put the file within the ear. If this was the case than I would not have any problem, because it works. The problem is that I want to externalize the properties and not put it in the ear. What I'm looking for is a way to do it in Java to set the classpath during runtime. I need help, because I never did it and any help would be greatly appreciated. Thanks for your response, but I'm looking for some way to do it during runtime.

Originally posted by Maulin Vasavada:
Hi Bob,

I didn't understand the following,
use the same datasource.xml file but the implementation is different for each one of them.

To me it looks like, you have TWO datasource files having different "content". XML DTD may be same for the files but the content is different. Is that what you have? If that is the case then I wouldn't put it as "Two EARs use the same file..." OR I didn't understand when you said "different implementations of the same file". How one can have "implementations" of the file??

Now, saying that, one way would be to just put those files in respective packages directory and getResourceAsStream() things would work for you to get the correct file as it would look for in the package first...

Please correct me if I am wrong.

Regards
Maulin
Maulin Vasavada
Ranch Hand

Joined: Nov 04, 2001
Posts: 1871
Hi Bob,

Okay. So you have 2 files datasources.xml with name and you want to put both of them in CLASSPATH in such a way that A.ear refers to one file and B.ear refers to other..

hmm...thats a problem I guess. As suggested earlier by folks , updating CLASSAPATH is not really possible by Java program.

I have not externalize the way you are mentioning. Somehow it seems fine to me that EAR is the whole thing. What issue do you really face if you put those files in the individual EAR files?

My suggestion is try to avoid CLASSPATH manipulations as far as possible (if it is possible in anyway..) because its pretty much controlled by App/Web servers and it would be good to avoid doing those things ourselves..

Regards
Maulin
[ December 06, 2004: Message edited by: Maulin Vasavada ]
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Just for completeness ... you can hack the classpath with unsupported calls to protected methods. Does that sound like hunting for a gas leak with a match? The custom classloader sounds safer.



A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
bob morkos
Ranch Hand

Joined: Oct 06, 2003
Posts: 56
That sounds like a solution for my problem. Can I set the classpath with a directory. Saying that any files under this directory, such as c://oc4j/j2ee/home/conf/a/properties/ (*.properties) Is there a way to do this, with your code below?


Originally posted by Stan James:
Just for completeness ... you can hack the classpath with unsupported calls to protected methods. Does that sound like hunting for a gas leak with a match? The custom classloader sounds safer.

 
GeeCON Prague 2014
 
subject: Dynamically setting classpath from java