Running an external program from an executable Jar - java

I have created a simple SWING gui for a cmd program someone else developed. To run this program I execute this line:
Process convertProcess = Runtime.getRuntime().exec("jlyt\\prog\\com_win\\jlyt.bat " + selectedFiles.getName());
The jlyt folder is in the same folder as my src folder (I am using IntelliJ).
When running via IDE everything works great, but not when I run the jar I created. I have tried running it from the directory it was saved to by IntelliJ as well as from the directory of the jlyt folder.
I did not add the external program (inside the jlyt folder) to my jar since it is very heavy. I want my jar to be distributed along side the original program and not to contain everything.
Any idea how I should build my jar?
Thanks.

I see why you put /jlyt in /src, it serves as a convenience within the IDE. /jlyt will get copied as a resource into /bin/classes, or whatever the IDE target is, and that allows everything to work from the IDE.
When you JAR your application, /jlyt is typically added to the JAR; however, it is not accessible to Windows. I assume you are placing a copy of /jlyt in the same folder as the JAR when you attempt to run.
As a first step, in a terminal, set the current directory to the folder containing the JAR and /jlyt. Since you are specifying a relative path in your exec(), that should be sufficient for everything to run.
You can also try creating a shortcut to the JAR, since it is executable, and set the working directory to the folder containing the JAR.

You have to use a relative path based on the place where jlyt.bat is according to your jar file.
e.g. use "./" or "../" to navigate the directory tree up.

The location of the JAR file is only relevant for starting the JAR. The working directory must be the directory that contains the jlyt folder, since you are using 'jlyt\...' as path to the executable.
Example, lets suppose following directory structure:
somewhere
project
gui
appl.jar
jlyt
prog
...
working directory must be 'project' and the JAR will then be referenced as 'gui\appl.jar
C:\somewhere> cd project
C:\somewhere\project> java -jar gui\appl.jar
Also be sure to wait for the convert process to terminate (e.g. convertProcess.waitFor()) before exiting your application/java - I believe that any running external process is killed when the Java Virtual Machine is closed!
Hint in documentation of Process:
As of 1.5, ProcessBuilder.start() is the preferred way to create a Process.

Related

Java - How does relative folder creation differ from non-compiled code to an executable

I am making a Java program that I will wrap to become an .exe for testing and production. Part of the programs initialization process is to make a folder named "config" on the same level as the executable file. For illustration:
---> Parent Folder
---> myProgram.exe
---> config/
That is what ideally what should happen.
As of now, I'm testing this block of code:
String config_dir = "./config";
if(!new File(config_dir).exists()){
new File(config_dir).mkdirs();
return;
}
And what it does is to check if the directory exists, and create it if it doesn't.
However, this code is run by my Main.java class, and when it goes one level higher to create the config directory, it is still on the same level as the other folders inside the workspace directory:
---> MyProject
---> bin
---> external_lib
---> src
---> config
Which makes sense since I only made the app create the folder one level higher. However, after it is packaged as an exe file, it needs to make that folder on the same level as the exe file. I am just worried that it might not work that way.
Does anyone have a way to ensure that a folder is created on the same level as the packaged executable Java file? I'm working on a Mac and it might take time to be able to test it.
From a "running a JAR" perspective, you could use
System.getProperty("user.dir")
which returns the path where the JVM was started from. Once you turn this into an executable, I'm unsure exactly what you might need. But you might also try
getClass().getProtectionDomain().getCodeSource().getLocation()
Java
Irrelevant.
How does relative folder creation differ from non-compiled code to an executable?
It doesn't.
I am making a Java Program that I will wrap to become an .exe for testing and production. Part of the programs initialization process is to make a folder named "config" on the same level as the executable file.
For that purpose you need to know the location of the executable file. For a C or C++ executable that is given by argv[0] of the main() method. For Java JAR files it is given by getClass().getProtectionDomain().getCodeSource().getLocation().
String config_dir = "./config";
That will create a folder in the current working directory of the user, same as returned by System.getProperty("user.dir"). Not 'at the same level as the executable file'.
However, this code is run by my Main.java class, and when it goes one level higher to create the config directory, it is still on the same level as the other folders inside the workspace directory:
It is still in the current working directory. Your workspace has nothing to do with it unless it is the current working directory.
However, after it is packaged as an exe file, it needs to make that folder on the same level as the exe file.
No. In the current working directory. Always. That's what . means.
Does anyone have a way to ensure that a folder is created on the same level as the packaged executable java file?
See above, but, judging by comments and what you've accepted in your own answer, I don't think that's what you actually want. I think you want it in the current working directory, and that's what you're getting. What the current working directory actually is depends on how you run the program, and where from. If you run from within the IDE you will get the IDE's idea of it. If you run from a command line you will get the shell's cwd. If you run by double-clicking you will get whatever cwd is defined for the double-click, which may be the directory of the executable or JAR file.

Building file.jar, External Executable File missing

Assuming that I use NetBeans 7.3 , I created a project that, in a nutshell, receiving as input a set of parameters, it returns as output a print on screen. The project is made up of a number of directories. Each directory contains a class (in file.class form). One of these directory contains an executable in C. I wrote it as the kernel of the Java project.
I built file.jar and I added it as a library in a new project. When I tried to test it, an error message made ​​me realize that the C written program is not was automatically added to file.jar under construction.
One of my first attempt to solve this problem was to manually add the C-executable file. By using the JAR command from the terminal on my Mac, I was able to update the file.jar adding the executable in the right subfolder.
This solution is not served because, moving from project to file.jar, the relative path that leads to the execution of the C-program has changed. So I tried to change this path seeing it from the point of view of file.jar. Yet this attempt was futile.
I defer to those with more experience than me in the packaging and distribution of Java content.
As far as I know, an operating system cannot directly execute an executable that is inside a zip file (which is what a jar file actually is). It has to be first extracted.
So your program could first open its own jar file and extract the executable file into a file on disk, then run that file.
You can create an installer program, to install both the jar file and the executable file to a suitable location on the user's disk.

How to make jar files that draw from a source folder

I've been wanting to make executable jar files with java lately. When executing my code with Eclipse it works perfectly. But when I use Eclipse to export the same code as a runnable jar, Most of my jars work except the ones that draw from separate source folders.
The jar will be made but when launched it will try and open and then just say to check to console for possible errors. I try and run the jar through the console with the command "java -jar test.jar". and It says it cannot access the jar. Any Ideas? Btw Im on a macbook pro osX. Thank you!!
picture of where my files are within eclipse
If you have a file you want to store in a jar and access from there, you don't really have a Java File any more. Look at Class.getResourceAsStream() and Class.getResource() - the first can give you an InputStream to the (used-to-be) file, the second returns a URL and can be used for things like images. Note that the file being accessed can be accessed relative to the package/folder location of the class or relative to a classpath root (by putting "/" at the front of the resource name ("/resource/funny.jpg")).
When you execute the jar from a command line, be aware that you have a thing called the "default directory"; it is a folder in which your commands execute by default. If your jar is not in the default directory, you have to specify a valid folder path to your jar to execute it.

Exporting java project from netbeans to executable jar

Used eclipse in the past fro java coding and didn't have many issues but decided to give netbeans a blast
I'm trying to create a jar file with all dependencies as one jar and yes am familiar with the java-web-start-option and also the jar actually exists in my dist folder once built.
Problem 1
All's good and well, I can launch the jar but seems not without its lib folder which contains: AbsoluteLayout.jar + beanbindings.jars. Something I will need to figure out as I go along.
I call a few batch scripts to complete differenet jobs for me in the java program e.g. one finds memory amounts and displays in a JTextArea. When I use the program within the netbeans ide all works fine.
Problem 2
When I launch the jar file thats in the dist folder it launches just fine but cannot find the batch/bash scripts at all. Below is the path I use within the program which as I mentioned works fine in the IDE and just wondering why it cant find the same path in the jar.
I assumed when I created and built like in eclipe it would make all these commands work in the existing jar in my dist folder (bin in eclipse ofc)?
String[] filepath = {"cmd.exe", "/C", "..\\Enterprise\\src\\enterprise\\batch\\memory.bat"}
Any suggestions, thanks in advance!
Just try to change your path. Just make a flag if it's in your ide then select this path, if not then use another path.
Try this link to get the application path in java.
Get the application's path

The dreaded java.lang.NoClassDefFoundError

I've looked through many of the existing threads about this error, but still no luck. I'm not even trying to package a jar or use any third-party packaging tools. I'm simply running from within Eclipse (works great) and then trying to run the exact same app from the command line, in the same location it's built to (getting this error). My goal is to be able to zip up the bin folder and send it off to be run by someone else via a command line script. Some details:
It's a command-line app and I'm using the commons-lang-2.4.jar for string utilities. That is the file that cannot be located (specificaly "java.lang.NoClassDefFoundError: org/apache/commons/lang/StringEscapeUtils")
I have that jar in my lib folder and have added it to my build path in Eclipse via right-click "Build Path -> Add to Build Path"
The .classpath file looks correct and contains the reference to the jar, but I assume that file is only used by Eclipse (contains this line: <classpathentry kind="lib" path="lib/commons-lang-2.4.jar"/>)
Could this be related to the Eclipse working directory setting? I have some internal template files that I created that are under src/templates, and the only way I can seem to get those to be seen is by setting the project working directory to AppName/src. Maybe I should be putting those somewhere else?
Let me know if any additional info would help. Surely this is something simple, but I've wasted too much time on it at this point. This is reminding me why I originally left Java back in '05 or so...
A NoClassDefFoundError basically means that the class was there in the classpath during compiletime, but it is missing in the classpath during runtime.
In your case, when executing using java.exe from commandline, you need to specify the classpath in the -cp or -classpath argument. Or if it is a JAR file, then you need to specify it in the class-path entry of its MANIFEST.MF file.
The value of the argument/entry can be either absolute or relative file system paths to a folder containing all .class files or to an individual .jar file. You can separate paths using a semicolon ;. When a path contains spaces, you need to wrap the particular path with doublequotes ". Example:
java -cp .;c:/path/to/file.jar;"c:/spacy path/to/classes" mypackage.MyClass
To save the effort of typing and editing the argument in commandline everytime, use a .bat file.
Edit: I should have realized that you're using an Unix based operating system. The above examples are Windows-targeted. In the case of Unix like platforms you can follow the same rules, but you need to separate the paths using a colon : and instead of an eventual batch file, use a .sh file.
java -cp .:/path/to/file.jar:"/spacy path/to/classes" mypackage.MyClass
Are you specifying the classpath to java on the command line?
$ java -cp lib/commons-lang-2.4.jar your.main.Class
The classpath setting you are setting in Eclispe are only for the IDE and do not affect how you application is run outside the IDE. Even if you use the Eclipse Functionality to export your application as an executable jar file there is no out of the box way to package all the jars your application depends on.
If you have packaged you application into a jar file called myapp.jar then running a command like below will run the application with the jar you depend on, if you have more than one just add them separted by ; on Windows or : on Unix:
java -jar myapp.jar -cp .;c:/pathtolibs/commons-lang-2.4.jar
If you are just running the classes directly then either run the folder containing your .class files will also need to be on the path (though I assume it already is since you are able to run the program and get errors).
Consider File -> Export -> Runnable jar to create a jar file which can be invoked directly with
java -jar yourProgram.jar
There are several variants depending on your needs.
Eclipse does not move any of the jars in your classpath into the bin folder of your project. You need to copy the util jar into the bin folder. If you move it to the root of the bin folder, you might be able to get away without any classpath entries but it's not the recommended solution. See #BalusC's answer for good coverage of that.
Eclipse doesn't build executable java classes by default. Don't ask me why, but it probably has something to do with using their own tools.jar (somewhere in plugins/org.eclipse.core ?) so that Eclipse can run without a JDK.
You can usually go to your project bin directory and do:
java -cp . MyClass
But if you have external jars, Eclipse handles those internally in another weird way, so you'll need to add those too.
make sure your jar commons-lang-2.4.jar in classpath and not redudance.
I ever add jar file to my classpath, and have 2 file jar in my classpath. After I delete it, work smooth

Categories

Resources