node-java icon indicating copy to clipboard operation
node-java copied to clipboard

java.lang.NoClassDefFoundError

Open blulas opened this issue 8 years ago • 18 comments

I have created a very small node.js application with Nodeclipse (Eclipse plugin). This small application simply calls a Java facade using a static method, and that facade in turn calls APIs for a commercial product, via a large set of JAR file dependancies.

I have a JAR file with custom java code which wraps the commercial product API. I compile this JAR file outside of node-js using JDK 8, BTW. My code around this API works fine within JUnit, since I have control over my classpath when running from JUnit. There are nearly 40 JAR files that are required to be on the classpath in order for my custom code to run, even though from a compiling perspective only one of those 40 JAR files are required.

In my node-js application I am using java.classpath.push() for each of those 40 JAR files. I have verified that the JARs are on the application classpath, as I have dumped the classpath in my Java wrapper to the console.

My Java code works fine from node-js until it reaches a line of code which calls the product API, and then it simply returns a java.lang.NoClassDefFoundError for the product API class that I am calling. It seems clear that the product API classes are not on the node-js classpath for some reason.

I have also verified that I am getting into my custom Java methods from node-js, so the failure is clearly at the point in the code where I need to reference the product API.

Any and all help would be greatly appreciated!!

blulas avatar Jun 29 '17 20:06 blulas

I have resolved this issue by pointing my java.classpath.push() calls using the direct path of the JAR files rather than a relative path.

blulas avatar Jun 29 '17 21:06 blulas

I have the same error:

C:\Projects\testMQ\node_modules\java\lib\nodeJavaBridge.js:227 var clazz = java.findClassSync(name); // TODO: change to Class.forName when classloader issue is resolved. ^

Error: Could not create class MyClass java.lang.NoClassDefFoundError: MyClass Caused by: java.lang.ClassNotFoundException: MyClass at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

My codes are: node.js var java = require('java'); java.classpath.push( ".");

var MyClass = java.import("MyClass"); var result = MyClass.addNumbersSync(1, 2); console.log(result);
JAVA: public class MyClass { public static void main(String[] args){ System.out.println("Now the output is redirected!"); } public static int addNumbers(int a, int b) { return a + b; } }

MPBatista avatar Jul 05 '17 12:07 MPBatista

Can you try console.log(path.resolve(".")); java.classpath.push(path.resolve(".")); to make sure the directory that you intended to add to the class path is correct.

On Wed, Jul 5, 2017 at 8:46 AM, Mateus Pereira Batista < [email protected]> wrote:

I have the same error:

C:\Projects\testMQ\node_modules\java\lib\nodeJavaBridge.js:227 var clazz = java.findClassSync(name); // TODO: change to Class.forName when classloader issue is resolved. ^

Error: Could not create class MyClass java.lang.NoClassDefFoundError: MyClass Caused by: java.lang.ClassNotFoundException: MyClass at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

My codes are: node.js var java = require('java'); java.classpath.push( ".");

var MyClass = java.import("MyClass"); var result = MyClass.addNumbersSync(1, 2); console.log(result); JAVA: public class MyClass { public static void main(String[] args){ System.out.println("Now the output is redirected!"); } public static int addNumbers(int a, int b) { return a + b; } }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/joeferner/node-java/issues/402#issuecomment-313092299, or mute the thread https://github.com/notifications/unsubscribe-auth/AAxXma9AtuaPmNJQdwfbw1dDGcXvx7I-ks5sK4WIgaJpZM4OJ24y .

joeferner avatar Jul 05 '17 12:07 joeferner

Hi, after I put the "path" component, everything is working well, thanks!

MPBatista avatar Jul 06 '17 17:07 MPBatista

I’ve tried this and I get an exception that path is unresolved.

Barry Lulas | Principal Decision Management Architect | Apex Process Consultants | 727-433-9839 On Wed, Jul 5, 2017 at 8:52 AM, Joe Ferner [email protected] wrote: Can you try console.log(path.resolve(".")); java.classpath.push(path.resolve(".")); to make sure the directory that you intended to add to the class path is correct.

On Wed, Jul 5, 2017 at 8:46 AM, Mateus Pereira Batista < [email protected]> wrote:

I have the same error:

C:\Projects\testMQ\node_modules\java\lib\nodeJavaBridge.js:227 var clazz = java.findClassSync(name); // TODO: change to Class.forName when classloader issue is resolved. ^

Error: Could not create class MyClass java.lang.NoClassDefFoundError: MyClass Caused by: java.lang.ClassNotFoundException: MyClass at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

My codes are: node.js var java = require('java'); java.classpath.push( ".");

var MyClass = java.import("MyClass"); var result = MyClass.addNumbersSync(1, 2); console.log(result); JAVA: public class MyClass { public static void main(String[] args){ System.out.println("Now the output is redirected!"); } public static int addNumbers(int a, int b) { return a + b; } }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/joeferner/node-java/issues/402#issuecomment-313092299, or mute the thread https://github.com/notifications/unsubscribe-auth/AAxXma9AtuaPmNJQdwfbw1dDGcXvx7I-ks5sK4WIgaJpZM4OJ24y .

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub [https://github.com/joeferner/node-java/issues/402#issuecomment-313093964] , or mute the thread [https://github.com/notifications/unsubscribe-auth/AP8tlagQbYgWcFU6H2yJhmiBuoiU_Pbjks5sK4ccgaJpZM4OJ24y] .

blulas avatar Jul 18 '17 20:07 blulas

@blulas, try to run:

npm install path

this installs the package path.

MPBatista avatar Jul 19 '17 12:07 MPBatista

@MPBatista Although the path package on npm has the same, it's clear something else is wrong, since it comes builtin and there should be need to install it separately on node.js, unless an updated path version is needed for previous versions of node.js

abdulhannanali avatar Aug 25 '17 21:08 abdulhannanali

Could you test with this:

#!/usr/bin/env node const path = require('path'); console.log( path.resolve("."));

var java = require('java'); var javaLangSystem = java.import('java.lang.System');

javaLangSystem.out.printlnSync('Hello World');

MPBatista avatar Aug 28 '17 14:08 MPBatista

Hi, @MPBatista, your script worked. In general your solution worked, but there is a little catch related to where to put the java.classpath.push() call. Please see the below explanation.

on ubuntu oracle java 1.8, node v6.11.1. node-java v0.9.0.

test code:

#!/usr/bin/env node const java = require('java'); const javaLangSystem = java.import('java.lang.System'); console.log(java.classpath); javaLangSystem.out.printlnSync('Hello World'); java.classpath.push(path.resolve('/home/vagrant/Downloads', 'sikulixapi.jar')); console.log(java.classpath); const Screen = java.import('org.sikuli.script.Screen');

output:

vagrant@desktop01:~$ node testjava.js [ '/home/vagrant/node_modules/java/commons-lang3-node-java.jar', '/home/vagrant/node_modules/java/src-java', pushDir: [Function] ] Hello World [ '/home/vagrant/node_modules/java/commons-lang3-node-java.jar', '/home/vagrant/node_modules/java/src-java', '/home/vagrant/Downloads/sikulixapi.jar', pushDir: [Function] ] /home/vagrant/node_modules/java/lib/nodeJavaBridge.js:227 var clazz = java.findClassSync(name); // TODO: change to Class.forName when classloader issue is resolved. ^

Error: Could not create class org.sikuli.script.Screen java.lang.NoClassDefFoundError: org/sikuli/script/Screen Caused by: java.lang.ClassNotFoundException: org.sikuli.script.Screen at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

at Error (native)
at Java.java.import (/home/vagrant/node_modules/java/lib/nodeJavaBridge.js:227:20)
at Object.<anonymous> (/home/vagrant/testjava.js:10:25)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)

The above problem is related to where the java.classpath.push() is called. By placing it before the first import the script worked as expected:

test code:

#!/usr/bin/env node const java = require('java'); java.classpath.push('/home/vagrant/Downloads/sikulixapi.jar'); const javaLangSystem = java.import('java.lang.System'); javaLangSystem.out.printlnSync('Hello World'); const Screen = java.import('org.sikuli.script.Screen'); var s = new Screen(); s.click('/home/vagrant/Projects/chrome.png');

output:

Hello World [log] CLICK on L(32,174)@S(0)[0,0 1920x1016] (563 msec)

xywang68 avatar Dec 15 '17 23:12 xywang68

its common problem of this api . I also faced this type problem.

arjunrai1t avatar Dec 18 '17 10:12 arjunrai1t

Hi @xywang68, you can just put the jar inside the same directory where is the code nodejs.

This is happen because nodejs doesn't work well with the relative path, so you need to force the code to find the class.

MPBatista avatar Dec 19 '17 18:12 MPBatista

i also done this but same things happens..

On 19-Dec-2017 11:33 pm, "Mateus Pereira Batista" [email protected] wrote:

Hi @xywang68 https://github.com/xywang68, you can just put the jar inside the same directory where is the code nodejs.

This is happen because nodejs doesn't work well with the relative path, so you need to force the code to find the class.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/joeferner/node-java/issues/402#issuecomment-352838723, or mute the thread https://github.com/notifications/unsubscribe-auth/AEU96LnzhMVYGeFeRli5e12_AcVsxxrOks5tB_p_gaJpZM4OJ24y .

arjunrai1t avatar Dec 20 '17 03:12 arjunrai1t

Following how I use to find the jars:

#!/usr/bin/env node const path = require('path'); console.log(path.resolve(".")); // var java = require('java'); java.classpath.push( "."); java.classpath.push( "../lib/com.ibm.mq.headers.jar"); java.classpath.push( "../lib/com.ibm.mq.jar"); java.classpath.push( "../lib/com.ibm.mq.jmqi.jar"); java.classpath.push( "../lib/com.ibm.mq.postcard.jar"); java.classpath.push( "../lib/com.ibm.mq.commonservices.jar"); java.classpath.push( "../lib/commons-logging.jar"); java.classpath.push( "../lib/connector-api-1.5.jar"); java.classpath.push( "../lib/jta-1.1.jar");

var MqSeries = java.newInstanceSync( "ca.commun.mq.MqSeries", config[ENV].nomRequete, config[ENV].nomProgramme, config[ENV].localQManager, config[ENV].sendQManager, config[ENV].sendQ, config[ENV].replyQManager, config[ENV].replyQ, config[ENV].channel, config[ENV].hostName, config[ENV].port, config[ENV].userId, config[ENV].password );

var message = MqSeries.sendReceiveSync( requete);

console.log( "Message=" + message);

MPBatista avatar Dec 21 '17 18:12 MPBatista

You can also use https://github.com/joeferner/node-java-maven which I wrote to help with Maven like dependencies.

joeferner avatar Dec 21 '17 21:12 joeferner

Please give me example for find jar in windows with path

On 22 December 2017 at 03:15, Joe Ferner [email protected] wrote:

You can also use https://github.com/joeferner/node-java-maven which I wrote to help with Maven like dependencies.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/joeferner/node-java/issues/402#issuecomment-353465444, or mute the thread https://github.com/notifications/unsubscribe-auth/AEU96GPRGguZzVJdsB0zU2ojdAxUU9LQks5tCtFxgaJpZM4OJ24y .

arjunrai1t avatar Dec 22 '17 06:12 arjunrai1t

Hi All, I am also getting the same error i tried all the above suggestions nothing is working for me. Any help is appreciated.

/opt/demo/node_modules/java/lib/nodeJavaBridge.js:227 var clazz = java.findClassSync(name); // TODO: change to Class.forName when classloader issue is resolved. ^

Error: Could not create class com.aline.demo.Demo1 java.lang.NoClassDefFoundError: com/aline/demo/Demo1 Caused by: java.lang.ClassNotFoundException: com.aline.demo.Demo1 at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

at Error (native)
at Java.java.import (/opt/demo/node_modules/java/lib/nodeJavaBridge.js:227:20)
at Object.<anonymous> (/opt/demo/test5.js:9:27)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:383:7)

aakashkumar667 avatar Apr 05 '18 12:04 aakashkumar667

Hi @xywang68, Im trying to use the same example that you did with sikulix on mac but it didnt output anything.

The java logo appear on the doc and thats it. Any ideas of what could have happen?

Im trying to implement the sikulix to create a image recognition framework on nodeJS

RenanChagas avatar Apr 25 '18 09:04 RenanChagas

Hi, @RenanChagas , most likely it is due to javaclass path configuration. The example I provided above is based on Linux (ubuntu 16.04), and we are able to run in ubuntu-desktop, xvfb-run and docker configurations.

xywang68 avatar Apr 25 '18 23:04 xywang68