Translate jardesc content into jar-command - java

I am making some WebFilters for our WebLogic server and I've got everything up and running.
The problem is how I package the filters into jar-files. If I use the following jardesc-file and create the jar-file from Eclipse, everything is working fine and WebLogic has no problems loading the webfilter class. But as soon as I try to manually create the jar-file using just jar.exe I am hitting ClassNotFoundExceptions when loading the webcontainer in WebLogic.
Working jardesc-file:
<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
<jardesc>
<jar path="C:/Workspace/Java/Jars/jars/corsfilter.jar"/>
<options buildIfNeeded="true" compress="true" descriptionLocation="/CorsFilter/corsfilter.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
<storedRefactorings deprecationInfo="true" structuralOnly="false"/>
<selectedProjects/>
<manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
<sealing sealJar="false">
<packagesToSeal/>
<packagesToUnSeal/>
</sealing>
</manifest>
<selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
<file path="/CorsFilter/.project"/>
<file path="/CorsFilter/.classpath"/>
<javaElement handleIdentifier="=CorsFilter/src"/>
</selectedElements>
</jardesc>
Current jar-command:
jar -cvf corsfilter.jar .project .classpath -C .\bin dk\akait\filters\cors\CorsFilter.class
The jar-command creates a jar-file that seems to be equivalent to the one generated using the jardesc-file in Eclipse, except for what looks like some kind of symbolic link to the META-INF-folder in the root of the jar-file.
Content of working jar-file:
Content of non-working jar-file
Can anyone explain what the right command for executing jar.exe is, given the jardesc-file?
Or
Can anyone explain what the META-INF file in the not working jar-file is?
Updated with output of jar-command run using jdk-1.8.0_111

As already mentioned in the comments. I would think this is more like a problem with WinRar as with the actually created jar-file. Probably eclipse doesn't use the jar command internally to create jar-files based on the jardesc descriptions. And the jar-files differ somehow in their internal structure.
However I'd suggest not to rely on the eclipse output, if you want to create a jar-file that you are going to distribute somewhere. I personally like gradle a lot and it is pretty easy to use.
Simply create a build.gradle file in you project root directory with the following content:
apply plugin: 'java'
// this is only needed, if you want to include the single file only
// by default all compiled files will be added to the output jar
jar {
include "dk/akait/filters/cors/CorsFilter.class"
}
task wrapper(type: Wrapper) {
gradleVersion = '3.3'
}
Run
%PATH_TO_YOUR_GRADLE_BINARIES%/gradle wrapper
This will generate a local wrapper bat file that is used to ensure you are using the desired gradle version.
Run
%PROJECT_ROOT%/gradlew.bat build
and locate the jar-file under
%PROJECT_ROOT%/build/libs
You will however need to follow some conventions and place your java sources under a folder called src/main/java for this to work out-of-the-box. Or follow this documentation to setup different source folders.

I don't think your command line is even correct.
As according to jar output
Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point]
[-C dir] files ...
And also http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jar.html
It is expect to be [manifest-file] and [entry-point] after [jar-file] name.
Try
jar -cvf corsfilter.jar -C . .project .classpath -C .\bin dk\akait\filters\cors\CorsFilter.class

Related

How to run java project from command line (works fine in eclipse, gradle)

I'v got a simple java program. I'm developing in Eclipse, using gradle, and I'm logging with log4j2. This all works fine.
When I come to run from the command line, I do a gradlew build which works, but when I run the jar I get an error:
java -jar build\libs\testproj.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
at com.xxxxxx.practice.App.<clinit>(App.java:17)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
I can see a bunch of log4j files in my userprofile.gradle folder, and I could run a gradle dist task and then got and unzip the resulting zip file and then point at the contents of that, but if there some way of avoiding this? Surely there's something I can add to the manifest or something so that I can run from the command line at will with no overhead?
To be clear, it's just the logging that has this problem. Other than that it runs, the tests work etc from the command line, and the logging works fine from eclipse.
Someplace in your eclipse project, you'll find a library (these end in .jar) named log4j.jar or org.apache.logging-log4j.jar or log4j-api.jar or something along those lines.
This jar contains the classes that are missing when you run this on the command line. Try it: jar tvf log4j.jar prints the contents of the jar and you'll find it contains, for example, org/apache/logging/log4j/LogManager.class.
During compilation and during running a java app, this class needs to be on the classpath. Eclipse is taking care of the compilation part of it.
If you run java as java com.foo.ClassName, the classpath is defined by the -cp parameter: java -cp testproj.jar:log4j.jar com.foo.yourapp.TestApp would work (use semicolon on windows instead). If you don't specify it, the system environment variable CLASSPATH is used, but you don't want that (you can run multiple java apps on one machine after all, so a global setting makes little sense).
If you run java using java -jar myjar.jar however, the classpath is solely taken from the jar file itself; inside the jar file is a file called META-INF/MANIFEST.MF and it contains (in text) key/value pairs. The relevant one is the Class-Path: foo.jar bar.jar entry: Space-separated listings of jar files, relative to the dir your jar is in.
You cannot use the -cp option when using the -jar option; the -cp option is ignored.
So, next steps:
I don't know if gradle made the Class-Path entry correctly. Best option is to use the jar or zip tool to unpack your jar to check that MANIFEST.MF file and see what's there. If there is, say, Class-Path: lib/log4j.jar in that file, then make sure that if testapp.jar is at /Users/Dev123456/project/testapp.jar, that that log4j jar is at /Users/Dev123456/project/lib/log4j.jar. If there is no class-path entry, then the error lies in your gradle config; you'd have to post your build.gradle file in that case.
There are 'striper plugins' which mix all the various jars together in one giant jar. This is usually a bad idea (it just makes the jar itself humongous, and makes builds take longer. If you're deploying java code to a server, you can manage the Class-Path entry by yourself, and if you are making a desktop app, you need an installer which... can manage the class-path stuff just as well. Really no reason to use stripers). I advise against using these.
Just run with java -cp yourapp.jar:dep1.jar:dep2.jar com.foo.fullyqualified.ClassName instead.
Try to run your jar by specifying Log4j jar as well in classpath and then mention your MainClass from testproj.jar :
java -cp build\libs\testproj.jar:build\libs\log4j.jar com.package.MainClass

How to add path to resource directory to an executable jar

I am trying to create an executable jar (code.jar) that depends on another jar file (other.jar) that I create in a separate project(=directory).
The problem I'm having is that there is a class in other.jar that looks for an image file (xyz.gif) that is contained within that project:
e.g., project 'other' looks like: build/ images/xyz.gif src/... etc.
I make other.jar (including the /images directory) and then I make code.jar.
However, when I run
java -jar code.jar - it is unable to locate xyz.gif:
java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(ImageIO.java...)
I have tried everything I can think of to communicate the path to images/xyz.gif to the jar, including:
1. I tried adding the CLASS-PATH: images/ to the MANIFEST.MF for other.jar
2. I tried copying the images directory into the build for code.jar and adding CLASS-PATH: images/ to the MANIFEST.MF for code.jar
3. I tried putting CLASS-PATH: images/xyz.gif - in both manifest files
This seems like a general problem: How to include a (non-class) resource (e.g., an image file) to a java jar file in
such a way that java can locate it (without subsequent packages that utilize the sub-package - e.g., code.jar uses other.jar)
needing to know the details.
Say I can successfullly run the code project using:
java -cp somepath/images com.xyz.code
What I want to do is run:
java -jar code.jar - and have it locate the images/ directory on the classpath.
I should add that the image-containing jar (other.jar) project is not my code - I am just trying to compile it to use. That code tries to load the image using:
javax.imageio.ImageIO.read(ClassLoader.getSystemResource("xyz.gif");
There seems to be a lot of discussion about whether this is the correct/best way to load an image - I assume that the authors of this code DID have it working using Eclipse (whi
ch likely sorted out the paths), and I simply want to get it working on the command line (and eventually in ant).
Any help would be greatly appreciated. I don't understand why the documentation on jar creation is so minimal.
Instead of running jar directly try putting it in classpath. Something like this:
java -cp code.jar MainClass
This might work.
EDIT:
Above solution will not work. Try the below code to get image.
ImageIcon myIcon = new ImageIcon( this.getClass().getResource("/resources/icon.gif"));
and place the image at below locations:
/myApp/src/resources/icon.gif
/myApp/bin/resources/icon.gif

Creating war file with jar command is not working properly

Hi all i have used the following command to generate war file from my spring project.
D:\projectsample\webContent>jar cvf projectsample.war
The war file is generating but when i deploying it using the jettyrunner.jar,its not deploying.I have noticed in the war file that there is no class files are generating inside the WEB-INF\class folder.Can anyone suggest me a solution for this problem.
"jar" command will not create .class files, it is for creating the package. So you have to compile the source files first, then use the jar command.
Also, you might need to add as parameter(s) the files you want to include, so something like
jar cvf myapp.war *
To add all files.
How To Create i.war in Java
1.Install Jdk
2.Set JAVA_HOME in Inviroment
3.cmd = >
4.c:\user> Cd D:\apex_listener
5.D:\apex_listener> jar -cvf0 D:\apex_listener\i.war -C Y:\APPLICATION_EXPERESS\apex_4.2.2_en\apex\images .

Making a JAR file which includes all files of a cetain type from any subdirectory

So this is a simplified version of my package structure
Project 1
-folder1
-folder2
-folder21
-folder211
-test3.java
-folder22
-folder3
-test4.java
-Project2
-folder1
-folder11
-folder111
-Test.java
-folder2
-.properties
-Test2.java
-folder3
What I want to find is command that will create a jar and take the paths to project1 and project2 and recursively add the folder structure and java files without adding the .properties files.
What i've tried so far is
jar cvf test.jar "pathtoproject1/.java" "pathtoproject2/.java"
That only works for java files in the base project directories not the subfolders.
Anyone know how to do this?
edit
This is for a batch script on windows
Frankly I'm not sure that jar handles this out of the box.
I suggest using ant - with an ant jar task, using a fileset.

Build project into a JAR automatically in Eclipse

I have an Eclipse project where I want to keep my Java project built into a JAR automatically. I know I have an option to export the project into a JAR; if I do a right click; but what I am really looking for is, that like Eclipse automatically builds a project's .class files and put them in target folder; it should also build a JAR automatically and copy the latest JAR at some or a specific location.
Is there a option to configure Eclipse in such a way, to build JARs automatically?
Just to make it clear for guys, patient enough to answer my question; I am not looking at ANT as solution; as I already use it, but what I would like it something that gets initiated automatically either with a time based trigger or immediate build with change.
You want a .jardesc file. They do not kick off automatically, but it's within 2 clicks.
Right click on your project
Choose Export > Java > JAR file
Choose included files and name output JAR, then click Next
Check "Save the description of this JAR in the workspace" and choose a name for the new .jardesc file
Now, all you have to do is right click on your .jardesc file and choose Create JAR and it will export it in the same spot.
Create an Ant file and tell Eclipse to build it. There are only two steps and each is easy with the step-by-step instructions below.
Step 1
Create a build.xml file and add to package explorer:
<?xml version="1.0" ?>
<!-- Configuration of the Ant build system to generate a Jar file -->
<project name="TestMain" default="CreateJar">
<target name="CreateJar" description="Create Jar file">
<jar jarfile="Test.jar" basedir="." includes="*.class" />
</target>
</project>
Eclipse should looks something like the screenshot below. Note the Ant icon on build.xml.
Step 2
Right-click on the root node in the project.
- Select Properties
- Select Builders
- Select New
- Select Ant Build
- In the Main tab, complete the path to the build.xml file in the bin folder.
Check the Output
The Eclipse output window (named Console) should show the following after a build:
Buildfile: /home/<user>/src/Test/build.xml
CreateJar:
[jar] Building jar: /home/<user>/src/Test/Test.jar
BUILD SUCCESSFUL
Total time: 152 milliseconds
EDIT: Some helpful comments by #yeoman and #betlista
#yeoman I think the correct include would be /.class, not *.class, as most
people use packages and thus recursive search for class files makes
more sense than flat inclusion
#betlista I would recomment to not to have build.xml in src folder
Check out Apache Ant
It's possible to use Ant for automatic builds with eclipse, here's how
This is possible by defining a custom Builder in eclipse (see the link in Peter's answer). However, unless your project is very small, it may slow down your workspace unacceptably. Autobuild for class files happens incrementally, i.e. only those classes affected by a change are recompiled, but the JAR file will have to be rebuilt and copied completely, every time you save a change.
Regarding to Peter's answer and Micheal's addition to it you may find How Do I Automatically Generate A .jar File In An Eclipse Java Project useful. Because even you have "*.jardesc" file on your project you have to run it manually. It may cools down your "eclipse click hassle" a bit.
Using Thomas Bratt's answer above, just make sure your build.xml is configured properly :
<?xml version="1.0" ?>
<!-- Configuration of the Ant build system to generate a Jar file -->
<project name="TestMain" default="CreateJar">
<target name="CreateJar" description="Create Jar file">
<jar jarfile="Test.jar" basedir="bin/" includes="**/*.class" />
</target>
</project>
(Notice the double asterisk - it will tell build to look for .class files in all sub-directories.)
Creating a builder launcher is an issue since 2 projects cannot have the same external tool build name. Each name has to be unique. I am currently facing this issue to automate my build and copy the JAR to an external location.
I am using IBM's Zip Builder, but that is just a help but not doing the real.
People can try using IBM ZIP Creation plugin.
http://www.ibm.com/developerworks/websphere/library/techarticles/0112_deboer/deboer2.html#download

Categories