Java Command Line Program Classpath Problem - java

so I have a pretty large project in Eclipse which runs fine and accesses files etc. And when in Eclipse I access files with a local directory name in relation to the root of the project directory.
So my project is called "Project1" for example and is inside a directory called "MyProjects" so it looks like this: "MyProjects/Project1". I want to access a file in the "MyProjects" folder called "hello.text". So I just do "../hello.text" and it works fine when I do this in Eclipse.
The problem I have is when I run the program using the command using "java Project1" it runs the program fine but it cannot access that file because when executing programs from the command line it stars them from the "bin" directory which is inside of the "Project1" directory. So it messes up the whole program. Is there anyway to change this easily in my Windows environment or Eclise? I hope my question makes sense. I want the program to execute from "Project1" directory if possible so I don't have to change the file location everytime.

You can use one of ClassLoader class methods
public URL getResource(String name)
or
public InputStream getResourceAsStream(String name)
to locate and access any resource in the classpath in a way that is independent of the location of the code. For exaple
InputStream myTextFileStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("Project1/Hello.txt") ;

How about providing a directory argument so you don't have to worry about it at all ever?

Can't you start your Java program from the bin directory's parent?
e.g.
Project1> java -classpath bin MyApp
Does this answer for getting classpath from Eclipse help?

Related

Absolute file paths when running program from jar?

I don't understand how Java jar files work. I am trying to understand what is possible and not possible when creating a Java jar file. Is it possible to have a String path running normally in a Java jar file? Will this normally work as it works when running main class in eclipse? I mean, I have an absolute path in my main class that grabs the file and reads from it.
public static final String file1 = "C:\\Users\\Documents\\test1.txt";
public static final String file2 = "C:\\Users\\Documents\\test2.txt";
This is what I have when running my program and it works fine. This is inside a class that is called somewhere along when I want to read a file. My question is... will this prevent my jar file from working properly normally AS when running the main class from eclipse?
I have the jar file but what if it doesn't or does it still look for file1 and file2?
It doesn't matter whether that code is in a jar file or not. The strings will still be exactly as they are, and if you pass them to methods that look for files with those paths, it'll look for files with those paths in the file system of the machine where the code is running. It won't look for them inside the jar file.
A Jar file is basically an executable of your project, it is used for example by frontend's who need a backend but don't want to open an IDE for compiling and executing purposes. Your Jar file contains .class files responsible for the execution of your project, you an execute your jar in a server too, so your application will run for more people (if you configure right).

How to get location of runnable .jar File when run from GNOME

I am developing a small Java application using Swing, that is supposed to run on Windows/Linux and MacOS.
Eventually it will ship as a runnable jar with some config files in the same folder. To load them I need the path to the folder the jar is stored in within the program.
There are already a couple of threads like this one or this one.
My problem is, that all the solutions discussed there work fine, when I run the program from within eclipse or call the runnable jar from a terminal like so:
java -jar /path/to/jar/jarfile.jar
However when I click on the jar file in Cinnamon or Gnome (which is what most of the users will know to do), I do not get the correct paths. (MacOS users report the same issue)
Here is what I've tried so far and what the output is when run via double click (all those display the desired path when run from eclipse or a terminal):
ClassLoader.getSystemClassLoader().getResource(".").getPath()
Output: file:/usr/lib/jvm/java-6-openjdk-common/jre/lib/ext/pulse-java.jar!/
SomeClass.class.getProtectionDomain().getCodeSource().getLocation().getPath();
Output: ./
System.getProperty("user.dir");
Output: /home/myusername
Is there any other way to do it or am I doing something wrong when exporting the jar? Any help would be appreciated!
Cheers
Nick
Make it simple, and use a startup script (.bat/.sh file) to run your application. This startup script will get the path of its own location in the filesystem, and pass it as an argument or system property to the Java application. This has the additional advantage of being able to pass other arguments, like the size of the heap, etc.
On windows, %~dp0 is the path of the directory containing the executed bat file. On Unix, you can use $(dirname $0).
You could store all config files as resources in a jar, and copy them to files in home.dir + ".AppName/".
Painful as it is, the Preferences API, Preferences.systemNodeForPackage, seems the wisest alternative, if there is little structured config data. There is an inputStream method for import; your initial config template could be a resource in the jar.
Just get the class path using System.getProperty("java.class.path") and scan it for your ".jar" name. Note that path separators are OS dependent (File.pathSeparator)

Java file access

At the moment, in my java program, I am accessing a file that is in the project folder. When I'm loading the file its path is "./src/package/package/file.txt". When I build the program into an executable it dosen't work.
I would prefer the files to be outside of the .jar, but in the same folder, how would I got about this?
Samishal
You can use a relative path if they are in the same folder, such as ./file.txt. That should carry over even with a compiled JAR.
Otherwise, if you're going to be using the same machine and are confident of the placement of the files, you could use an absolute path, however I don't recommend it.
You can use Class.getResourceAsStream to get the InputStream. It works for jar package too. It is not possible to access the file in jar file using File API directly.
InputStream ins = Class.getResourceAsStream("/gigadot/exp/resource.properties");
More details at http://blog.gigadot.net/2010/10/loading-classpath-resources.html
Because the relative path is relative to where your command prompt is when you execute the program, not from where the program lives.
You somehow need to tell the program where to find resources. Most people use a .sh/.bat script to figure out where the script itself lives, and either pass -D flags or set the classpath based on that location.
as a note, I $0 gives you the script as it was run on the command line in linux (it could be relative or absolute), and you can use dirname from there to find it's directory, and alter the java command line.
in windows %~dp0 gives you the directory of the batch script which was run, and you can use that to form your java command line.

Again "wrong name" error when executing java program

With reference to this post
Receiving "wrong name" NoClassDefFoundError when executing a Java program from the command-line
I did not understand how to solve the problem
Actually in my java source code there' s line :
package es_2011;
when I compile the program through JCreator everything works perfectly.
It creates a folder named es_2011 where to put .class files.
Also the executing operation goes smoothly, the program runs ok.
Now I'd like to use the command line only.
So I placed my java file in the directory where javac.exe is but whenever I try to compile I get the same error
The command I use is: javac ProgAudioJ.java
The path (where javac.exe is ) is : C:\Program files\Java\jdk1.6.0_22\bin
Is someone willing to help me understand in terms of exactly tell me what I have to do?
thanks very much...MAX
The setup used for the looks like this (under windows)
C:\classDir -> is the project
C:\classDir\testpackage -> is the only package used (the package "testpackage")
C:\classDir\testpackage\Main.class -> is the class with the main method inside (important: it is the .class and not .java)
The Main.class looks like following:
package testpackage;
public class Main {
public static void main(String[] args) {
System.out.println("Program started! ;-)");
}
}
go with your command prompt to:
c:\classDir> java testpackage.Main
the result:
Program started! ;-)
According to your problems that it starts in your IDE but not from the console:
- checked if you realy use the path to the .class files?
- with the console go to the directory of you .class files, not the project (e.g. in Eclipse it is the bin directory
- enter the full qualified class name (including packages seperated by . -> e.g. testpackage.Main
More infos can be found under:
http://www.oracle.com/technetwork/java/compile-136656.html
Hope it helped
MAX, if the class defines that it's inside the package es_2011, then it should be in a folder with the same name.
So in your case, put the ProgAudioJ.java in the folder es_2011 and then run
javac es_2011\ProgAudioJ.java
latter to run it, you need the command
java es_2011.ProgAudioJ
You should add javac.exe in your path .Edit your path variable and append path to jdk's bin
then put java file in a dir named es_2011 , as the package declaration is es_2011 then compile
c:\es_2011\javac YourJava.java
and now go back to C:
c:\java es_2001.Yourjava
After reading you other Post: "Receiving "wrong name" NoClassDefFoundError when executing a Java program from the command-line" I guess you go to the directory es_2011 where your ProgAudioJ.class file is located and run
java ProgAudioJ
from that folder.
instaend you have to go to the folder above (cd ..) and run
java es_2011.ProgAudioJ
Each package in Java corresponds to a folder on the filesystem. So a package declaration such as com.stackoverflow would mean that the source classes need to be in a folder ./com/stackoverflow. Typically the whole project would have a separate src folder containing com/stackoverflow.
When you compile the Java classes you DO NOT need to put source files in the same directory as javac.exe, you do however need to make sure that javac.exe is in your operating systems PATH variable. This tells the operating system where it should look for executable files when a command is run, on a *nix machine this would usually be /usr/bin or just /bin but on Windows machine the executables normally live within the applications own directories, that is C:\Program Files\something. Assuming that you've installed JDK correctly, the javac.exe should already be in the PATH you can check this by opening the command line and just running javac (just like that). If you get some output then all is well, the system knows where to find javac.exe.
Next you will need to go to your project folder and type javac -d . src/com/stackoverflow/MainSO.java notice that is run from the project folder. This will create a folder called com in your project root and put the compiled classes in com/stackoverflow. The -d flag tells javac where to put the compiled classes, if you leave that out, the compiled classes will be where the sources are.
Then when you want to run the classes you type java com.stackoverflow.MainSO (no .class). Crucially this command will need to be ran in the directory that contains the root of the class hierarchy (that is the com folder containing the compiled classes). You can specify other places for java to look for the classes by providing a classpath to the java command with the -cp flag. By default the classpath will contain the directory the java command was ran in. Should your project have dependencies external .jar files for example you will need to provide every single one of them (with their full filepath) in the classpath (this goes for the compiler as well). The IDEs do this automatically for you.
Hope that helps.

Java: Loading resources from the file system

My Project Setup
I have the following project setup:
\program.jar
\images\logo.png
In my code, I reference the image with the relative URL "images/logo.png".
Problem
If I run this program with the following command while in the directory:
c:\projects\program_dir\bin\>java -jar program.jar
Then everything works and Java is able to locate the image.
Now, my problem is, that I need to be able to run the program from a different directory.
c:\>java -jar c:\projects\program_dir\bin\program.jar
The program is executed, but now all the relative URLs no longer work.
What I need
How do I calculate the execution home of the program.jar file, so that I can change my relative URLs into absolute URLs?
What I would do, if possible, is package your images in with your Jar.
That way you don't have to worry about where your Jar is launched from.
You would then need to load images similar to the following:
InputStream stream = this.getClass().getClassLoader().
getResourceAsStream("/images/logo.png");
You should really include your resources in your JAR.
Failing that, you can parse the absolute path out of the Main class resource. Assuming your Main class is actually called "Main":
Main.class.getResource("Main.class").getPath();
Resources have to be in the class path(s). You may try one of these:
Placing the images into the program.jar.
Like most of the programs, they have a APP_HOME directory, e.g. MAVEN_HOME, register that and refer to your files as File instead - $APP_HOME/the-file.ext (with System.getenv()).
As Nelson mentioned, package them with your JAR (just copy them alongside your .class files), then you can find them via a simple this.getClass().getClassLoder().getResource("images/foo.png").
You need to add a parameter which describes your class path. Should look something like
java -cp c:\projects\program_dir\bin -jar program.jar
this will put your jar and image on the class path and it will load successfully.

Categories