Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

How does one locate the java executable and various JAR files in the classpath?

Thread view: 
Oliver Wong - 09 Dec 2005 19:58 GMT
   Note: This post mentions Eclipse to show what parts of the design I have
no control over, but I believe you don't actually need to know much about
Eclipse development to help contribute a useful answer.

   I have a JAR file which does some useful stuff, including generating
some files into the "current directory". That is, it creates new File
objects using relative paths, and so these files appear relative to the
directory from which the JAR was invoked. I can read the source code for
this JAR, but I'm pretty much not allowed to make changes to the code in it.

   I'm writing a plugin for Eclipse, and one of the functionalities is to
invoke this JAR. That is, I want to give the user the ability to right click
somewhere in their project hierarchy, and select "Generate files here" from
the context menu, and in responce to that, I'll invoke the JAR file, passing
it command line arguments based on settings that the user specified earlier.

   The cleanest solution, I think, would have been to invoke the static
main function in the JAR directly, 'cause then I could catch any exceptions
thrown from there and handle them specially, but I think there is no way to
set the "current directory" in Java, and so doing this would result in my
not being able to control where the files get generated.

   The next solution that came to my mind was to use Runtime.exec(String,
String[], File)

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html#exec(java.lang.St
ring,%20java.lang.String[],%20java.io.File
)

   Thanks to the last argument, I can specify the working directory for the
subprocess.

   However, I'm not at a lost of how to construct the String for the first
parameter. I want to run the "java" interpreter, something of the form:
"java -jar myHelper.jar Other Command Line Arguments", but this assumes both
that "java" and "myHelper.jar" can be found from the current working
directory, which will not nescessarily be the case.

   Any advice on how to find both the java executable and the jar file? Or
how to programmatically affect the current working directory (so that I may
use the original cleaner solution)?

   - Oliver
Andrew Thompson - 09 Dec 2005 22:28 GMT
>     Any advice on how to find both the java executable and the jar file?

URL urlToClass = this.getClass().getResource(
  "get/any/class/in/mysterious/Jar.class" );

I am sure there is also something more specific for classes,
just cannot recall it.

Signature

Andrew Thompson
physci, javasaver, 1point1c, lensescapes - athompson.info/andrew

Oliver Wong - 09 Dec 2005 22:50 GMT
>>     Any advice on how to find both the java executable and the jar file?
>
[quoted text clipped - 3 lines]
> I am sure there is also something more specific for classes,
> just cannot recall it.

   I had actually tried:

this.getClass().getClassLoader().getResource("myMysteriousJARFile.jar");
//[1]

... but null was returned. The JAR file is on my classpath at compile time,
but I'm not so sure it's there at invocation time when Eclipse invokes my
plugin (though I suspect it should be, or else how could I call methods
located within that JAR?)

   I also strongly suspect that Eclipse uses its own custom classloader for
loading plugins. Not sure how that might affect the above code's ability to
locate my JAR.

   - Oliver

[1]: I want the JAR file, and not any particular class within the JAR,
because I want to construct a string to pass to Runtime.exec(). Something
like Runtime.exec("java -jar /path/to/jar/myMysteriousJARFile.jar", null,
myDesiredWorkingDirectory); I was hoping to take the URL from the
classloader, assuming it points to the local filesystem, and then convert it
to an absolute path using the File class.
DM McGowan II - 10 Dec 2005 04:01 GMT
> [1]: I want the JAR file, and not any particular class within the JAR,
> because I want to construct a string to pass to Runtime.exec(). Something
> like Runtime.exec("java -jar /path/to/jar/myMysteriousJARFile.jar", null,
> myDesiredWorkingDirectory); I was hoping to take the URL from the
> classloader, assuming it points to the local filesystem, and then convert
> it to an absolute path using the File class.

Is it possible to write a class loader then load the JAR rather than take
the performance hit of running a separate Java process? Just curious.
Roedy Green - 09 Dec 2005 23:13 GMT
On Fri, 09 Dec 2005 22:28:45 GMT, Andrew Thompson
<seemysites@www.invalid> wrote, quoted or indirectly quoted someone
who said :

>I am sure there is also something more specific for classes,
>just cannot recall it.

you were thinking of getProctectionDomain?

import java.net.URL;
import java.security.CodeSource;

/**
* Find out where a class on the classpath will be loaded from.
* Fully qualified classname goes on the command line.
*/
public class Where
  {
  /**
   * main
   * @param args name of fully qualified class to find, using dots,
but no dot class.
   * e.g. java.exe Where javax.mail.internet.MimeMessage
    */
  public static void main ( String[] args )
     {
     try
        {
        String qualifiedClassName = args[0];
        Class qc = Class.forName( qualifiedClassName );
        CodeSource source = qc.getProtectionDomain().getCodeSource();
        if ( source != null )
           {
           URL location = source.getLocation();
           System.out.println ( qualifiedClassName + " : " + location
);
           }
        else
           {
           System.out.println ( qualifiedClassName + " : " + "unknown
source, likely rt.jar" );
           }
        }
     catch ( Exception e )
        {
        System.err.println( "Unable to locate class on command line."
);
        e.printStackTrace();
        }
     }
  }
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Andrew Thompson - 09 Dec 2005 23:21 GMT
> On Fri, 09 Dec 2005 22:28:45 GMT, Andrew Thompson
> <seemysites@www.invalid> wrote, quoted or indirectly quoted someone
[quoted text clipped - 4 lines]
>
> you were thinking of getProctectionDomain?

Spot on ..well, without the initial 'c', but yes.

Signature

Andrew Thompson
physci, javasaver, 1point1c, lensescapes - athompson.info/andrew

Oliver Wong - 09 Dec 2005 23:56 GMT
> import java.net.URL;
> import java.security.CodeSource;
[quoted text clipped - 38 lines]
>      }
>   }

   Thanks, after embedding your code into my project, I was able to confirm
that the JAR I was seeking was not on the classpath at runtime. I've fixed
that, and now your code does return the correct path to the JAR file. You've
helped me a lot. Thank you.

   - Oliver
Oliver Wong - 10 Dec 2005 00:25 GMT
> I've fixed that, and now your code does return the correct path to the JAR
> file.

   Just in case anyone is curious, I solved the other problem, of locating
Sun's java executable, like this:

System.getProperty("java.home") + "/bin/java";

   - Oliver
Rhino - 09 Dec 2005 22:30 GMT
>    Note: This post mentions Eclipse to show what parts of the design I
> have no control over, but I believe you don't actually need to know much
[quoted text clipped - 37 lines]
> how to programmatically affect the current working directory (so that I
> may use the original cleaner solution)?

Wouldn't it be more appropriate to ask your questions on a suitable Eclipse
forum? (Don't ask me which one: there are lots of them and I always get lost
trying to find the right one :-)

Rhino
Oliver Wong - 09 Dec 2005 23:04 GMT
> Wouldn't it be more appropriate to ask your questions on a suitable
> Eclipse forum? (Don't ask me which one: there are lots of them and I
> always get lost trying to find the right one :-)

   I posted it to eclipse.newcomer on Eclipse.org's usenet server, but
since I thought the question doesn't specifically rely on knowledge of
eclipse, it might be worth asking it here as well. Hopefully people will
excuse the multi-posting as the messages lie on completely detached servers.

   - Oliver
Rhino - 10 Dec 2005 00:44 GMT
>> Wouldn't it be more appropriate to ask your questions on a suitable
>> Eclipse forum? (Don't ask me which one: there are lots of them and I
[quoted text clipped - 5 lines]
> excuse the multi-posting as the messages lie on completely detached
> servers.

I'm not complaining :-)

Rhino
Chris Uppal - 10 Dec 2005 14:15 GMT
>     I have a JAR file which does some useful stuff, including generating
> some files into the "current directory". That is, it creates new File
> objects using relative paths, and so these files appear relative to the
> directory from which the JAR was invoked.

[I see that you've already found a workaround, and anyway this is just an
observation.]

IMO, any API that /depends/ on the idea of a "current directory" is broken in
this day and age.  There's nothing wrong with allowing relative filenames to be
specified as inputs to the API, but it seems foolish to create files in
locations that the user (programmer) can't control.

Perhaps you can encourage the authors of your JAR to un-break the API ?

   -- chris
Roedy Green - 10 Dec 2005 22:21 GMT
On Sat, 10 Dec 2005 14:15:31 -0000, "Chris Uppal"
<chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly
quoted someone who said :

>IMO, any API that /depends/ on the idea of a "current directory" is broken in
>this day and age.  There's nothing wrong with allowing relative filenames to be
>specified as inputs to the API, but it seems foolish to create files in
>locations that the user (programmer) can't control.

It makes not much sense in a multithread program.  Each thread would
need its own version of the CWD.

Your problem really is Windows There are so many ways to invoke a
program it is easy to get confused what CWD you are giving it.

Some experiments are in order . Just display the CWD first thing on
the console, and experiment till you feel confident you have it under
control.

See http://mindprod.com/jgloss/file.html
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.