I have a simple Java program (lets call it MyProgram.java) that does some I/O, re-names some images, deletes a directory, etc. I've been browsing around S/O looking for a simple way to run a Java program's main method from command prompt. I've compiled the source code into a jar, and tried using Jar2EXE Wizard, however I kept getting an unexpected compilation error that I wasn't getting while running my code from the IDE.
Does any one have either a Jar -> EXE converter solution they've had success with or can walk me through how to run my program from a batch file?
[..]or can walk me through how to run my program from a batch file?
The simplest way is to execute:
java -jar YOUR_JAR_FILE.jar
in your batch file. However this requires a manifest file to be present in your jar file which specifies the Main class to use and jar files it depends on. If you do not want to work with a manifest file you can specify these things manually. If you do not depend on external jar files you can execute:
java -cp YOUR_JAR_FILE.jar some.package.Main
This will execute the public static main(String[] args) method in class some.package.Main contained in YOUR_JAR_FILE.jar.
If there are other jar files you depend on (in your case that would be IOUtils/FileUtils), specify those jar files as well:
java -cp YOUR_JAR_FILE.jar:library1.jar:library2.jar some.package.Main
(in your case library1 and library2 are IOUtils and FileUtils respectively).
You can specify any number of jar files and you can also use the wildcard *.jar to include all files in the current (or another) directory. Note however that you cannot write * or x*.jar or the like. Only *.jar (or some/directory/*.jar) is accepted.
In 90% of the times, the order of the jar files does not make any difference. However sometimes it does make a difference: If a resource is loaded from the classpath (could be a class or something as simple as a configuration file), the jar files are searched in the order you specified. If a resource exists in multiple jar files, only the first one found will be used.
You can consider using install4j.
If you want use batch file you can write this:
java -jar sources.jar
If your code have more than 2 static void main(String[] args) you need explicitly hit the method:
java -jar sources.jar classes.package.Main
Directory structure:
-\project\
-\project\run.bat
-\project\sources.jar
Take a look at JSmooth. It wraps your JARs as executables and provides options for detecting, and handling lack of, the JVM. I've used it on a simple app and it was painless.
Bonus: it is available as a portable app with no installation needed.
Related
I currently wrote a simple GUI in Eclipse which runs as intended. I was hoping to export it so I can share it with my friend (who doesn't need to install eclipse and the java libraries). I tried all 3 library handling method Eclipse provides and none of them works. I read a little online and saw something about a manifest file, but wasn't quite sure what to do with it. Is it going to help?
This is where I placed the folder that comes with the .dll file.
This is the result. Am I doing something wrong?
As indicated by the error messages in the first screenshot, what you are missing here is the native library - the software library written and compiled to native code specific to the operating system. What you will need to do is provide the libraries specific to the operating system on which your software will run, eg. dlls for 32 or 64 bit Windows. The manifest does not provide the capability to include those libraries.
When the program is run on Windows, Java will look for native libraries in the following locations:
The current directory
The directories in the PATH environment variable
The directories in java.library.path (if it's specified)
It may be easiest to simply put all files in the one directory. If you do this, you should be able to run the program in the same way as you do now.
The java.library.path option is only needed if you want to put your native library files in a directory separate to the one in which you run your program and not on your PATH. It is only in this case that you will need to add java.library.path, eg. by adding -Djava.library.path=c:\path\to\your\lib after java. Also note that you may use a relative path, ie. a path that is relative to the directory you are in when you execute the command.
I also see from your later error messages that you have another dependency, but on a java library LeapJava.jar. As running a jar with -jar will only work if you have a single jar, but because you have more than one (your own program plus the dependency), you'll instead need to use the -classpath (or -cp for short) argument and add your main class. The classpath argument is a semicolon-separated list of classpath locations, while the main class is the one containing your public static void main method, eg. your.package.name.YourMainClass. So assuming your UI.jar is still in C:\Users\Ian\Desktop\Leap Data UI, you should be able to navigate to that directory and execute with:
java -cp UI.jar;UI_lib\LeapJava.jar -Djava.library.path="UI_lib\x64" your.package.name.YourMainClass
I am trying to execute a compiled version of my program attachmentUploader.jar from the command line. This has a number of dependencies on various Java libraries, which I am planning to bundle up with the program and specify as part of the classpath. This package will be moved between environments, and will be executed using the Java runtime for that environment. Using absolute paths for my environment, the command looks like this:
"C:\Program Files\Java\jdk1.6.0_37bin\java" -cp "C:/Users/My Documents/jars/attachmentLoader.jar";"C:\Dev Tools\jxl.jar";"C:\Dev Tools\org.apache.commons.codec";"C:\More Dev Tools\java-json.jar" com.custom.test.postClient
I would like to amend all the classpath jar paths to be relative to where my main class is saved, but I read that relative paths in this situation would be relative to where the Java is executed from. In my case this could be anywhere, as it will depend on where this has been installed. Is there a straightforward way of getting round this?
Thanks all.
There are actually several ways:
Make your jar file an executable jar file. That is done by adding a manifest file to the jar specifying what the main class is, and where the jar dependencies are located, relative to the location of the main jar file. The command to execute the program would then be java -jar path\to\jarfile.jar
Use a wrapper executable or shell script, that uses the location of the script itself to compose the classpath. Such a script would depend on the system (Unix/Windows), but both platforms allow script files to know their own location, and thus to use that location as a basis for the location of jar files. An advantage of that technique is that it also allows passing system properties, memory options, etc. to the JVM.
I recommend you use a standard build tool such as gradle, which has an application plugin generating all those script files for you, for all platforms, and bundles the whole application into a zip or tar.gz file.
Uploaded a jar file from my computer to a server and tried to run it. When I run it I get java.lang.NoClassDefFoundError and it seems to be related to the twitter4j jar that my main method depends on.
However, I have this jar file in my libraries so shouldn't this be included when I build my code in to a jar? Here's a pic in case it helps.
is the error that I'm getting. (can't upload a pic just yet.
Not sure what this has to do with twitter, but anyway, the issue is that you do not have the correct class files. In other words, when you are running your fat JAR in the command prompt, you do not have any libraries exported with it (Or if you do, you don't have that specific one).
Sometimes such an error can be because there is an incorrect version of java, however that is not the case here since java has got no "twitter" packages or classes in it.
Using something like JarSplice would fix this.
Assuming you did not package the twitter4j classes inside your application jar, you need to tell Java where it can look for classes that are not inside your application jar. You typically use the classpath flag for that. In your case, it should look something like
java -cp /tmp/twitter4j.jar -jar /tmp/myapp.jar
An alternative would be to package all twitter4j's classes inside your application jar. This is called a 'fat' jar. How to make one depends on how you build your application jar.
The JAR file that you are trying to use needs to be in the classpath. This can be done by using the -cp attribute from the command line. However, when using java -jar, you cannot use the -cp attribute.
To get around this, you can do the following:
java -cp /tmp/myapp.jar;\path\to\external.jar com.example.package.MyClass
where MyClass has the main() method defined.
Alternately, you can specify jar files on the classpath using the manifest.mf file. See http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html for details.
I have written a quick Java wrapper that fires off the NMAP executable and waits for it to finish. I am using Eclipse. I would like to include the NMAP source/executable
in my Java jar file so that I have a self-contained package.
Within Eclipse I have added the NMAP folder hierarchy. Within Eclipse I can see Java firing off the NMAP utility correctly, and waiting for the utility to end before exiting.
So far, so good. I then export a JAR file for with eclipse. I can see the NMAP folder hierarchy present. However when I try to run the JAR file it is having trouble finding nmap.exe. Can a foreign executable be called from with a jar file? if not, what are
my options? If so, why can't it find it within the jar file when it could find it within Eclipse?
Thanks.
You will need extract the .exe and its required support files onto the disk before you can access them as regular files (which execution through standard methods requires, I believe). You can look up examples of how to copy a resource from a jar to a file using getResourceAsStream() on one of your class files in the jar.
Once extracted, you can execute is as you are doing now (you might need to ensure execution rights, etc. based on your OS)
The "execute native program" facility does not understand how to invoke EXE-files inside other files (like ZIP or JAR).
If you want to do this, you must extract the files to a file system location and invoke it there. Due to the diversity of Linux distributions (PowerPC? other library versions etc) you should probably ask the user to install it instead and invoke that instead of bringing your own.
To my knowledge, you cannot execute an executable embedded in a jar file.
One solution would be to embed the executable in the jar file. Then use getClass().getResourceAsStream("/path/to/executable") to retrieve the bytes and output them to a temporary file (File.createTempFile()). On UN*X system, you will have to chmod u+x file before trying to execute. Eventually, you could delete the temp file or create the file once and reuse it everytime and call deleteOnExit().
Of course, this solution implies that you have executable(s) that work on all platforms.
Your solution probably works in eclipse because your "executable" file is not in a jar.
You may also have to be careful of how you are distributing this because Nmap isn't free for use in commercial software.
There is an open source library for Java to call Nmap but it assumes that Nmap is installed on the OS on which you are running your code. That API is Nmap4j and it is on sourceforge.net.
Consider a Java program, launched from a main method, that needs something from tools.jar. In this case, some utility code for connecting to JMX services. Do we have any choice but to wrap it in a shell script that uses -cp to manage the class path? We'd much rather use a MANIFEST.MF classpath.
from http://java.sun.com/developer/Books/javaprogramming/JAR/basics/manifest.html
the URLs in the Class-Path header are given relative to the URL of the JAR file of the applet or application.
I do not believe you have a choice about using a shell wrapper to get the tools.jar on your classpath. unless you write some custom classloader internally to allow you to find external jars.
If incorporating classes from the dependency jar is an option, I'd go with creation of a "Runnable JAR file". Basically you extract the classes from it and put them with your own classes in the JAR. That eliminates the need for a wrapping script.
To do that in Eclipse, select your project, File -> Export -> Java -> Runnable JAR file; that option will require that you have executed the main class at least once to know what profile to run when you actually run produced JAR.