Jar file fails to run, extracted class runs fine - java

I apoligize if this has been asked before but I have been unable to find anything that is the same.
I created a simple jar(myFailingJar.jar) file with two classes a main class and a simple class that accesses a class and its functions from another jar file (CCJAPI.jar).
The main class just instantiates the simple class, the simple class loads a shared library object and calls a function within CCJAPI.jar that crosses over JNI.
When run as a jar file with this command it fails because it can't find a class in CCJAPI.jar which is on the classpath:
java -classpath /home/scott:/home/scott/CCJAPI.jar -jar myFailingJar.jar
Starting
Exception in thread "main" java.lang.NoClassDefFoundError: ccjni/DeviceManager
at DetachedManager.DetachedDeviceManager.startManager(DetachedDeviceManager.java:24)
at DetachedManager.Main.main(Main.java:19)
Caused by: java.lang.ClassNotFoundException: ccjni.DeviceManager
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
If I extract the contents of the myFailingJar.jar file and run with this command it works, which as far as I can tell just goes to the extracted class files and runs the :
java -classpath /home/scott:/home/scott/CCJAPI.jar DetachedManager.Main
Starting
** Started **
Success = - Going to crash now
Here is both source files contents:
Source of Main
package DetachedManager;
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
DetachedDeviceManager devMgr = new DetachedDeviceManager();
if( devMgr.startManager() )
{
System.out.println("Success = - Going to crash now");
}
}
}
Source of simple class:
package DetachedManager;
import ccjni.DeviceManager;
public class DetachedDeviceManager {
{
System.load("/usr/lib/libccJNI.so");
}
public boolean startManager()
{
System.out.println("Starting");
DeviceManager.start();
System.out.println("** Started ** ");
return true;
}
}
The only difference is that one is tyring to run the compiled class from within the jar file and the other is running it outside the jar file. It must be some type of classpath or path issue that I have not been able to figure out. Any help would be much appreciated.

You probably are not creating the correct jar with the correct dependancies. Use the eclipse export (Right click on a project --> Export), This will also create the required manifest file.
Using this should be helpful.

When I specified the classpath on the command line I thought that should be sufficient for any jar file loaded into the java environment to find a jar file, apparently it is not. I ended up having to add the class path into the manifest file even though that path was specified on the command line.
Here is the failing manifest:
Manifest-Version: 1.0
Created-By: 1.6.0_0 (Sun Microsystems Inc.)
Main-Class: DetachedManager.Main
Here is the successful manifest
Manifest-Version: 1.0
Created-By: 1.6.0_0 (Sun Microsystems Inc.)
Class-Path: lib/CCAPI.jar
Main-Class: DetachedManager.Main
Thanks to all for listening and giving me an idea of where and what to look at.

Related

class file in JAR seems to be ignored; class file being picked up from directory on classpath instead

I am trying to get a simple JAR file executing on the CLI (without a manifest). The folder structure is as follows:
mods\un.jar
out\test\Main.class
src\test\Main.java
Here is Main.java:
package test;
public class Main{
public static void main(String []args){
System.out.println("Unnamed module...");
}
}
Here are the commands from the root folder:
javac -d out src\Main.java
java -cp out test.Main - this works
jar -cvf mods\un.jar out\test\Main.class
java -cp mods\un.jar;out test.Main - works (when 'out' is in classpath)
java -cp mods\un.jar test.Main - ERROR
The last line generates the errors:
Error: Could not find or load main class test.Main
Caused by: java.lang.ClassNotFoundException: test.Main
I have looked at the JAR zip and it looks ok. The MANIFEST.MF is the default one but that is okay as I am explicitly telling Java what class to start with (the class with main()). The contents are:
META-INF\MANIFEST.MF
out\test\Main.class
The manifest itself is:
Manifest-Version: 1.0
Created-By: 11 (Oracle Corporation)
So it looks like the class file in the JAR is not being picked up at all. If I omit the out folder when I run java or if I rename the .class file in the out folder), I get the class not found error. I would like to get it working without a manifest.
Any ideas?
Thanks,
Seán.
You need to change to the 'out' directory to get your package root correct in the jar:
jar -cvf mods\un.jar -C out test\Main.class

Importing .jar file in a project whitout IDE and getting ClassNotFoundException

I'm trying to import a .jar file in my project whitout using IDE and the way I'm doing everything works fine until I run the program. I'm getting the following error message when I run it.
So, I created this bar-project folder which I created the .jar file.
bar-project/resources
bar-project/src/com/bar/packmain/Bar.java
Bar.java:
package com.bar.packmain;
public class Bar {
public Bar() {
System.out.println("Bar.");
}
}
At the folder bar-project/src/ I'm compiling like this:
javac -d . com/bar/packmain/Bar.java
To create the jar file I'm using the follwing command:
jar -cvf Bar.jar com/bar/packmain/Bar.class
Then I move this .jar to my other project called foo-project.
foo-project/resources
foo-project/library/Bar.jar
foo-project/src/com/foo/packmain/Foo.java
Foo.java:
package com.foo.packmain;
import com.bar.packmain.Bar;
public class Foo {
private Bar bar;
public Foo() {
new Bar();
}
public static void main(String[] args) {
new Foo();
}
}
At the foo-project/src/ folder I'm compiling and running like this:
javac -cp .:../library/Bar.jar -d . com/foo/packmain/Foo.java
java com.foo.packmain.Foo
Exception message:
Exception in thread "main" java.lang.NoClassDefFoundError: com/bar/packmain/Bar
at com.foo.packmain.Foo.<init>(Foo.java:10)
at com.foo.packmain.Foo.main(Foo.java:14)
Caused by: java.lang.ClassNotFoundException: com.bar.packmain.Bar
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 2 more
So, my question is how can I fix this?
You compiled the project without an error:
javac -cp .:../library/Bar.jar -d . com/foo/packmain/Foo.java
But your command to run your application doesn't include the Bar.jar in classpath.
You have to include your JAR file here, too:
java -cp .:../library/Bar.jar com.foo.packmain.Foo
This is a good way to learn how these things work at the lower level and you get a better understanding what higher levels tools like an IDE or Maven really do.

I get an error: An unexpected error occurred while trying to open file hola.jar

i am using Linux ubuntu and i have created a java program named hola.java which is the following program code, this program works perfectly
import javax.swing.*;
import java.awt.*;
public class hola extends JFrame {
JButton b1 = new JButton("presionar");
hola(){
super("Botones");
setSize(250,250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout flo=new FlowLayout();
setLayout(flo);
add(b1);
setVisible(true);
}
public static void main(String[] args)
{
hola bt = new hola();
}
}
This java program works perfectly when it runs
Now I created a jar file of this program using in command line:
jar cf hola.jar hola.class
This creates a Jar file named hola.jar
I even wrote Main-Class: hola in the manifest.mf file.
When I try to run this by:
java -jar hola.jar
I get an error: An unexpected error occurred while trying to open file hola.jar
Please tell me how to run jar file so that I get an output :'( , what could be the possible reason that i can not run this program as a jar file, even the program works perfectly using "java hola.java"
This error mostly indicates invalid MANIFEST.MF file. Perhaps long line, missing final line terminator, accidental empty line in the middle, ... many things can go wrong. Using -cp just goes around the problem, but does not fix the root cause.
To run a java file within a jar file, you don't need to open it. You simply need to ensure your classpath is having the given jar file
If the class is within a package then you can run using
java -cp hola.jar package.hola
If the class is not in a package then simply use
java -cp hola.jar hola
If you are not within the directory where hola.jar is located, then you can try following:
In case of within package
java -cp /locationOfJar/hola.jar package.hola
or In case of not in package
java -cp /locationOfJar/hola.jar hola
Error can also happen with > 65535 files in the .jar on some OS
I experienced same error message attempting to launch via -jar:
$ java -jar app.jar
Error: An unexpected error occurred while trying to open file: app.jar
Root cause is that my sbt-assembly output .jar file contains more than 65535 entries.
$ zipinfo app.jar |wc -l
65543
Solution: Short term solution was removal of older dependencies to lower the number of assembled .class files below the 16 bit file count limit.
Long term solution will involve testing Zip64 jvm support on the target OS. Unsure of why the zip64 auto negotiation isn't occurring automatically.
This issue is reproducible using sbt-assembly 15.0, openjdk version "11.0.8" on MacOSX 10.15.7.
Start of the code review:
package java.util.zip;
...
public
class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
/**
* Whether to use ZIP64 for zip files with more than 64k entries.
* Until ZIP64 support in zip implementations is ubiquitous, this
* system property allows the creation of zip files which can be
* read by legacy zip implementations which tolerate "incorrect"
* total entry count fields, such as the ones in jdk6, and even
* some in jdk7.
*/
private static final boolean inhibitZip64 =
Boolean.parseBoolean(
GetPropertyAction.privilegedGetProperty("jdk.util.zip.inhibitZip64"));

Unable to locate resource outside of Jar

I've a java program as shown below:
package com.abc.myproject;
import java.util.*;
class test {
public static void main(String[] args)
{
ResourceBundle rb = ResourceBundle.getBundle("mybundle");
String propertyValue = rb.getString("name");
System.out.println("propertyValue="+propertyValue);
}
}
I've this program located under C:\testing\code\src\com\abc\myproject\test.java
And, I've kept mybundle.properties under C:\testing\code folder.
mybundle.properties contain one line:
name=Mike
When I run the program from command prompt as shown below, it runs perfectly fine:
C:\testing\code\src>java -cp .;c:\testing\code com.abc.myproject.test
propertyValue=Mike
Now, I created Jar file xyz.jar containing only test.class & kept this Jar in C:\testing directory & the manifest of jar contains below:
Manifest-Version: 1.0
Created-By: 1.7.0_05 (Oracle Corporation)
Main-Class: com.abc.myproject.test
In the same directory C:\testing, I kept mybundle.properties & then tried to run jar with below commands:
java -cp .;c:\testing -jar xyz.jar
But it fails to load mybundle resource & throws error:
Exception in thread "main" java.util.MissingResourceException: Can't find bundle
for base name scheduler, locale en_US
at java.util.ResourceBundle.throwMissingResourceException(Unknown Source)
at java.util.ResourceBundle.getBundleImpl(Unknown Source)
at java.util.ResourceBundle.getBundle(Unknown Source)
at com.abc.myproject.test.main(test.java:8)
I have to keep the mybundle.properties out side of Jar since we should be able to make changes in this file without having to redeploy the Jar.
Can any one please help me in fixing this issue?
Thanks!
java -cp .;c:\testing -jar xyz.jar
You cannot add to the classpath when using -jar. $CLASSPATH and -cp are ignored, and it will only use the classpath in the jar manifest.
What you can do is run your class like this:
java -cp .;c:\testing;xyz.jar com.abc.myproject.test

Running java code on VMWare with references to external jar files

I am trying to run simple java code on VMWare Workstation. I have the following simple test Main file:
import cern.jet.random.engine.RandomSeedGenerator;;
public class TestDataService {
//private static Logger logger = Logger.getLogger(TestDataService.class);
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello World DAI!");
// Input some data.
RandomSeedGenerator re = new RandomSeedGenerator();
return;
}
}
RandomSeedGenerator is a class in colt.jar library, and I have the jar file under my lib folder.
I am building the project with ant, and I have the following manifest file where I set the classpath:
Manifest-Version: 1.0
Main-Class: edu.umass.TestDataService
Name: edu/umass/TestDataService/Version.class
Class-Path: lib/colt.jar
When I run the code from the VMWare shell which runs Red Hat Linux, I get this Exception:
[root#localhost] java -jar app.jar
Hello World DAI!
Exception in thread "main" java.lang.NoClassDefFoundError: cern/jet/random/engine/RandomSeedGenerator
at edu.umass.TestDataService.main (Unknown Source)
Caused by: java.long.ClassNotFoundException: cern.jet.random.engine.RandomSeedGenerator
Just as a final note, everything seems to work fine on windows with eclipse, but nothing seems to work on the virtual machine. Any ideas?
Did you install the jar files required by your application on the VMs?
Did you configured CLASS_PATH correctly?
I doubt there is an issue with the jvm or the vm. The problem is going to be in how you run the class. Specifically how your setting the classpath. Try this:
Navigate to where you've placed colt.jar. Get the present working directory by typing in pwd. Use this to construct the run command using the absolute path to colt.jar.
So eventually you should be running (from the directory containing your jar) something like this:
java -cp /the/full/path/to/lib/colt.jar -jar app.jar
Once you've got that work you can then try and figure out what the correct relative path is. and then you'll be able to do
java -cp a/relativel/path/to/lib/colt.jar -jar app.jar

Categories

Resources