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.
Related
I developed a simple java application ,is it possiblefor the application (Executable Jar File) to find its current path and delete it self from both the current place and from Recycle Bin after a certain time.
No, when java runtime starts and uses this jar file, windows prevents it from being deleted. In other operating systems like Linux you can delete files even if they are used.
There are already questions/answers that show you how to get the currently running jar file. Keep in mind, the methods aren't consistent across platforms:
How to get the path of a running JAR file?
Deleting a file in Java is fairly straight forward as well:
import java.io.File;
...
new File("c:\\path\\to\\whatever.jar").delete();
On an operating system that doesn't have file locking, you can simply delete the jar you're running from as it's already loaded into memory. On operating systems that lock files, this may not be possible if the JVM decides to lock the currently executing jar(s).
Windows strictly restricts you from doing this untill the jar is in use
It is something like this :
In Linux you can do it here is How to delete a executing jar file
In order to delete the jar file, I recommend:
Creating a bat/sh file
Run the file
Close the jar file with System.exit method
Within the bat/sh file:
Loop until success deletion
Delete the bat/sh file within itself(unlike the jar file bat/sh file can delete itself)
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.
I have an application that includes some executable script files. And I know that target machines on which we'll be deploying the application have java. Hence I am packaging the application up in a java archive and extracting on the target machines with "jar xf jarFileName". But the executable scripts are no longer executable. Yes, we can run "chmod _x scriptName". But is it possible for the scripts to be executable after extraction from a jar file without user intervention? I've already read: this related question but that isn't trying to maintain executability.
Well a JAR file is really a ZIP file, so this question covers most of what you are asking: Maintain file permissions when extracting from a zip file using JDK 5 api
The problem is that things like execute bits are OS specific, and there are all sorts of issues in making them work across different operating systems. The "execute" bit is no exception. A typical (external) ZIP file extractor should be able to cope with this (modulo that the relevant info is in the ZIP file in the first place!). But doing this when you extract the ZIP / JAR file programatically would involve unpicking the "extra data" byte array ... I think. I don't know what the jar command does ... though you could look at the source code if you are game ...
If you know that the file / script that you are extracting should be executable, I'd advocate simply modifying your extraction procedure to set the execute bit(s) appropriately after the extraction. In Java 7, you can do this thing the new NIO file attribute APIs. Or run chmod externally. You could also try extracting with a unzip utility rather than jar ... though that assumes that the platform has unzip installed.
If you want to deploy on Windows as well as unixes such as OS X, there are DOS/Windows versions of standard utilities such as chmod that are freely available. You could distribute those with your application, most likely, and set the path up so that your Windows chmod.exe is found by your install script if and only if there's not a native version available, as there would be on a unix system. You'd of course have to do enough testing on different systems to make sure that this won't fail in some not-to-unusual context.
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)
I would like to ship my application as a self-contained jar file. The jar file should contain all the class files, as well as two shared libraries. One of these shared libraries is written for the JNI and is essentially an indirection to the other one (which is 100% C).
I have first tried running my jar file without the libraries, but having them accessible through the LD_LIBRARY_PATH environment variable. That worked fine.
I then put the JNI library into the jar file. I have read about loading libraries from jar files by copying them first to some temporary directory, and that worked well for me (note that the 100% C library was, I suppose, loaded as before).
Now I want to put both libraries into the jar, but I don't understand how I can make sure that they will both be loaded. Sure I can copy them both to a temporary directory, but when I load the "indirection" one, it always gives me:
java.lang.UnsatisfiedLinkError: /tmp/.../libindirect.so: /libpure.so: cannot open shared object file: No such file or directory
I've tried to force the JVM to load the "100% C" library first by explicitely calling System.load(...) on its temporary file, but that didn't work better. I suspect the system is looking for it when resolving the links in libindirect.so but doesn't care about what the JVM loaded.
Can anyone help me on that one?
Thanks
One way would be to spawn another Java process from the first, generating the appropriate invocation script.
The jar is invoked by the user
The libraries are extracted to a temp directory
A (bash) script is written to the temp directory
this sets/exports the necessary environment variables
this launches the second JRE instance
The code makes the script executable
The code invokes the script
I know, spawning two JRE instances to launch one app would not be my first choice either.
If you are using Eclipse IDE, then this answer might help you.
I had same problem in eclipse windows that I couldn't added dependant .class files from the JNI.
After searching for a while I came to know that "Its a known bug inside Eclipse", In order resolve the same, I ported all the code to NetBeans IDE.
Can not add all the classes files from the JNI folder in Eclipse (JAVA, Windows 7)