Launch4j EXE cannot find Annotated Classes in embedded JAR - java

I am using Launch4j to create an EXE from a JAR.
The JAR file works fine when run with java -jar jarfile.jar.
However, when I run the executable, I run into problems.
The code looks for classes with a specific annotation using AnnotationDetector. I'm debugging through it and I find that Thread.currentThread().getContextClassLoader() returns jar:file:/C:/Windows/Temp/executable.exe!/com/package/of/annotated/classes/.
When I try to look through the JAR file "file:/C:/Windows/Temp/executable.exe!", it doesn't find my classes because it's assuming that the segment after jar:, namely jar:file:/C:/Windows/Temp/executable.exe!, is a JAR, but it is not.
Why is the resource URL being generated as that?
OR
How can I navigate through the EXE as I would have the JAR?
OR
How can I fix it so that my classes are found?
I'm looking for any help I can get. However, I'd like to not hardcode the classes into a static list, but rather to allow runtime discovery.
Thanks!

Related

Converting to jar or exe

I have around 10 java files with their corresponding class files. The whole application works when i execute one of the main class. I execute it using cmd. I need help converting it into a single self executing file. eg: exe or jar
A jar file is little more than just a zip of all classes and resource files. You need to add details into META-INF/MANIFEST.MF file so that the class containing the main method to be executed is know.
This should help: Link
You can try invoking the jar file as follows:
java -cp <jarfile.jar> <Complete.Package.ClassNameWithMainMethod>
You can make jar by Exporting the project using following methods in Eclipse IDE
File->Export->Java->JAR.
Note: This is already have a solution to change to exe or JAR.
How can I convert a .jar to an .exe?

java.lang.NoClassDefFoundError with jar files

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.

How to create Windows executable from JAR

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.

Running an internal exe in java

Im able to run exe's in runtime via Runtime.getRuntime().exec(filePath), but this only seems to work for external exe's outside of the jar. I want to run an exe that I've packaged inside of the jar. How would I do this? I'd believe theres a jar load function, because I've seen code that loads it the same way using the name of the file in the jar, but that returns an IO error for me.
You can copy it to a temporary location outside the jar file, I think that is possible.

tools.jar dependency

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.

Categories