Runnable jar with Apache POI - apache-poi

I'm trying to export my program as a runnable jar, packing the necessary libraries (Apache POI). The .jar is created, but it doesn't work. Is there a catch on deploying with these libraries? Because the program itself runs great from eclipse.

A few questions to ask yourself in this situation:
Where does the program fail? Are there any errors in the console? Are you running from the command line (java -jar myJAR.jar) so that you can see console output?
Okay, so you get a NullPointerException for the read file. Is the read file inside the JAR, or where is it? How does the program know where the read file is?
Is there really a problem with the way the JAR is packaged, or is it the way your code locates and reads in the file? Perhaps your code assumes a relative location which cannot be resolved when run from the JAR.

There are the following strategies.
Create your jar. Put it to chosen directory. Put there all dependencies of your application. Create script (shell script, batch file etc depending on your platform) where the java command line is either written hard coded or is generated. The line must include the class path, e.g.
java -cp myapp.jar;poi.jar com.company.MyMain
Create indeed runnable jar, i.e. jar that can be executed using command like java -jar myapp.jar. If your application has dependencies this jar must have MANIFEEST.MF file that defines class path using property Class-Path
Pack all your classes and all your dependencies into one large jar file.
Obviously all these operations should be automated either home made script or by one of available build tools.

Related

How to protect exe file made using Launch4J?

I have one critical issue to solve. I have one critical application written in JAVA, Build executable JAR file out of it and now using launch4J to warp it in EXE for Windows.
My main aim is to hide JAVA code/Classes from the user as it contains some algorithms and info which is sensitive.
The problem I am facing here is explained step by step:
1) I have One JAVA Application
2) From IntelliJ, I have created an executable JAR file from my project which has main() method and other critical algorithms implemented.
3) To protect my Java Code from reverse engineering, I have used launch4J utility and I got one EXE file as an output
4) Now during testing I have right Clicked on this EXE file and Extracted using WinZip. (By selecting Extract here... option)
5) Now I can see all the classes extracted from the JAR file I have provided to build EXE.
6) By this, Now my code is clearly visible. ( Even after Obfuscation, Some keys (Strings) are visible which is a kind of sensitive info for our project)
Solution I am looking for
1) Can I encrypt my JAR file in such a way that, No one will be able to read the code (I know obfuscation is the way, but to as JVM will not understand machine level code, somewhere code has to be translated to byte code and that will be visible through java class de-compiler), but if still there is any other way to do this?
2) Is it possible to protect EXE to get UnZipped?
3) Can I protect my EXE to be unziped by using some Password?
4) Any IntelliJ plugin to build EXE file from java code? (Ahead Of time compilation I am talking about)
5) Any other possibility?

How to make a GDSL file in a jar get picked up in another project in Intellij?

I have a project with a GDSL file that describes a DSL delegate like:
def ctx = context pathRegexp: ".*installer\\.groovy", scope: scriptScope()
contributor(ctx) {
delegatesTo(findClass("com.whatever.InstallerBase"))
}
I package this file up in the jar (just in the root of the jar) using maven.
In a separate project I have a maven dependency on my jar artifact containing the gdsl. However, my autocompletion doesn't work. It works fine with the sample scripts in the first project (with the GDSL).
Is there a step that I'm missing in order for the GDSL to be picked up? Do I need to place it in a special folder in the jar?
The problem was indeed what #PeterGromov indicated in the comment on the question:
ensure that the library jar is only attached as classes and not library source as well
both the source and library were configured and thus IDEA doesn't include it. I have opened a youtrack issue to fix this here:
https://youtrack.jetbrains.com/issue/IDEA-137411

How can symlink affect loading persistence.xml

In my project there're two different persistence.xml appearing in two different jar files after building. If I run application using command like this
/jre/v1.7.0_21/bin/java -cp patch:/path_to_app_jars/*:. org.somepath.MainClass
one of them is loaded but if I run it using symlink another one is peaked up
bin/ -> path_to_app_jars
/jre/v1.7.0_21/bin/java -cp patch:/bin/*:. org.somepath.MainClass
And this result is consistent regardless of what else I change.
How could that be?
My guess is that the expanded jars are returned in a different order when using the symlink, and it is loading the persistence.xml from the first jar listed.
As described in the java documentation, the order in which the jar files are returned when using a directory wildcard (*) is unpredictable. In order to always have the same jar loaded first, the solution is to list the jars explicitly in the classpath instead of using a directory wildcard:
The order in which the JAR files in a directory are enumerated in the
expanded class path is not specified and may vary from platform to
platform and even from moment to moment on the same machine. A
well-constructed application should not depend upon any particular
order. If a specific order is required then the JAR files can be
enumerated explicitly in the class path.

Groovy script classpath issue with SystemClassLoader

I'm writing a Groovy script which uses third party java code that I can't change.
This code uses (badly, I think) ClassLoader.getSystemClassLoader().getResourceAsStream("/hard/file/path/in/jar/file")
and expect to read a file.
Everything goes well from Java when using java -cp "/path/to/jar/file" ...
However, the third-party code is now to be integrated with a bunch of Groovy code we've already written, so we wanted to run it from groovy.
So we wrote a Groovy script, let it call test.groovy, and ran it as groovy -cp "/path/to/jar/file" test.groovy.
The problem is that code can't access the file resource, as it seems Groovy doesn't load its jars in the System ClassLoader directly.
For proof, with Thread.currentThread().getContextClassLoader().getResourceAsStream("/hard/file/path/in/jar/file") within the Groovy Script, I can read the file, but with ClassLoader.getSystemClassLoader().getResourceAsStream("/hard/file/path/in/jar/file"), I can't.
So, does anyone know how to load the class in System ClassLoader from a Groovy Script without beginning to try some dirty hacks (like metaclassing getSystemClassloader to return the context classloader)?
You could try adding the jar to the system classloader as well when your script runs, like so:
ClassLoader.systemClassLoader.addURL new File( '/path/to/jar/file' ).toURI().toURL()
PS: I assume you mean ClassLoader.getSystemClassLoader() in your question, rather than System.getSystemClassLoader()
You can try to put your jar into %GROOVY_HOME%\lib folder or make a wrapper around your groovy command and modify %CLASSPATH% variable before you start your Groovy process.

How to find the path of a running jar file

I'm trying to programmatically find the full path of a jar file while it's running. I know there are a number of other questions about this, but none of them seem to work for me - most notably, I've stumbled across
MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().gĀ­etPath()
a number of times. That particular method works for me when debugging in Eclipse, but once I compile to a jar, it returns a NullPointerException. Other methods have met similar problems after compiling.
I have a temporary workaround by using java.class.path, but that only returns the full path when I execute the jar from the GUI - in the terminal, it fails.
I should also note that the only system that I'm having this problem on is Linux. On Windows and Mac, I have no troubles.
Any help would be appreciated :)
Thanks!
Derek
EDIT: The jar is executable, if that changes anything.
You can't do it. There is no requirement for ClassLoaders to support this, and most don't.
Or, perhaps this formulation would be more helpful. Binary classes come into the JVM via ClassLoader objects. ClassLoader objects are not required to keep any track of the provenance of the classes they load. And they can load them from anywhere: a jar, over the web, a database, an old tin can.
So, if you want to always know the provenance of classes in your application, you have to always load code with a class loader that, indeed, does track provenance in a manner useful to you.
If you control the entire application, you can do that.
If you don't control the entire application, and are rather talking about an arbitrary jar loaded into an arbitrary class loader in an arbitrary app, you can't depend on learning its location.
The following works for me even when running from a jar file:
URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation();
String p = URLDecoder.decode(url.getFile(), "UTF-8");
File jarFile = new File(p);
Sending the path through the URLDecoder is important because otherwise a pathname with %20 in it will be created if the directory contains spaces.

Resources