New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot link Java class com.util (java.lang.NoClassDefFoundError: com/util (wrong name: com/Util)) #4861

Closed
javalovercn opened this Issue Nov 21, 2017 · 5 comments

Comments

Projects
None yet
3 participants
@javalovercn

javalovercn commented Nov 21, 2017

  1. new Eclipse Java project, and add a class named 'SecondUtil.java' in package 'com.util'
package com.util;

public class SecondUtil {
	public SecondUtil(){
		System.out.println("SecondUtil");
	}
}
  1. add a class named 'TestMain.java' in package 'com'
package com;

import org.jruby.embed.ScriptingContainer;

public class TestMain {
	public static void main(final String[] args) {
		final ScriptingContainer sc = new ScriptingContainer();
		sc.runScriptlet("Java::com.util.SecondUtil::new()");
	}
}
  1. import lib jruby-complete-9.1.14.0.jar
  2. run TestMain, console prints 'SecondUtil', all is OK.
  3. add a class 'Util.java' in package 'com' to current project
package com;

public class Util {
	public Util(){
		System.out.println("this is Util.");
	}
}
  1. run TestMain, console prints following error:
NameError: cannot link Java class com.util (java.lang.NoClassDefFoundError: com/util (wrong name: com/Util))
  method_missing at org/jruby/javasupport/JavaPackage.java:259
          <main> at <script>:1
Exception in thread "main" org.jruby.embed.EvalFailedException: (NameError) cannot link Java class com.util (java.lang.NoClassDefFoundError: com/util (wrong name: com/Util))
	at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:131)
	at org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:1307)
	at org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:1300)
	at com.TestMain.main(TestMain.java:8)
Caused by: org.jruby.exceptions.RaiseException: (NameError) cannot link Java class com.util (java.lang.NoClassDefFoundError: com/util (wrong name: com/Util))
	at org.jruby.javasupport.JavaPackage.method_missing(org/jruby/javasupport/JavaPackage.java:259)
	at RUBY.<main>(<script>:1)
  1. change jruby-complete-9.1.14.0.jar to jruby-complete-1.7.3.jar
  2. run TestMain, it works well.
@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 21, 2017

Member

So we are having problems locating a class when there's a package of the same-but-lowercase name.

@kares You've done a lot of tweaking and optimizing of Java integration...perhaps some search order got reversed, or we're using the package name to try to load the class?

Member

headius commented Nov 21, 2017

So we are having problems locating a class when there's a package of the same-but-lowercase name.

@kares You've done a lot of tweaking and optimizing of Java integration...perhaps some search order got reversed, or we're using the package name to try to load the class?

@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 21, 2017

Member

@javalovercn Is there a reason you closed this? I was able to reproduce locally, so I do believe this is a bug.

Member

headius commented Nov 21, 2017

@javalovercn Is there a reason you closed this? I was able to reproduce locally, so I do believe this is a bug.

@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 21, 2017

Member

@kares The following fixes the problem for me and does not cause any regressions. Please review. Needs a test, obviously.

diff --git a/core/src/main/java/org/jruby/javasupport/Java.java b/core/src/main/java/org/jruby/javasupport/Java.java
index e481b7d113..73e8e7326b 100644
--- a/core/src/main/java/org/jruby/javasupport/Java.java
+++ b/core/src/main/java/org/jruby/javasupport/Java.java
@@ -961,13 +961,16 @@ public class Java implements Library {
             // cannot link Java class com.sample.FooBar needs Java 8 (java.lang.UnsupportedClassVersionError: com/sample/FooBar : Unsupported major.minor version 52.0)
             throw runtime.newNameError("cannot link Java class " + className + ' ' + msg, className, ex, false);
         }
+        catch (NoClassDefFoundError | ClassNotFoundException ncdfe) {
+            // let caller try other names
+            return null;
+        }
         catch (LinkageError ex) {
             throw runtime.newNameError("cannot link Java class " + className + ' ' + '(' + ex + ')', className, ex, false);
         }
         catch (SecurityException ex) {
             throw runtime.newSecurityError(ex.getLocalizedMessage());
         }
-        catch (ClassNotFoundException ex) { return null; }
 
         if ( initJavaClass ) {
             return getProxyClass(runtime, JavaClass.get(runtime, clazz));
Member

headius commented Nov 21, 2017

@kares The following fixes the problem for me and does not cause any regressions. Please review. Needs a test, obviously.

diff --git a/core/src/main/java/org/jruby/javasupport/Java.java b/core/src/main/java/org/jruby/javasupport/Java.java
index e481b7d113..73e8e7326b 100644
--- a/core/src/main/java/org/jruby/javasupport/Java.java
+++ b/core/src/main/java/org/jruby/javasupport/Java.java
@@ -961,13 +961,16 @@ public class Java implements Library {
             // cannot link Java class com.sample.FooBar needs Java 8 (java.lang.UnsupportedClassVersionError: com/sample/FooBar : Unsupported major.minor version 52.0)
             throw runtime.newNameError("cannot link Java class " + className + ' ' + msg, className, ex, false);
         }
+        catch (NoClassDefFoundError | ClassNotFoundException ncdfe) {
+            // let caller try other names
+            return null;
+        }
         catch (LinkageError ex) {
             throw runtime.newNameError("cannot link Java class " + className + ' ' + '(' + ex + ')', className, ex, false);
         }
         catch (SecurityException ex) {
             throw runtime.newSecurityError(ex.getLocalizedMessage());
         }
-        catch (ClassNotFoundException ex) { return null; }
 
         if ( initJavaClass ) {
             return getProxyClass(runtime, JavaClass.get(runtime, clazz));

@headius headius reopened this Nov 21, 2017

@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 21, 2017

Member

@kares I went ahead with it because everything JI-related looked ok.

I also figured out this was probably introduced when you cleaned up the RaiseException nonsense in getProxyClassOrNull in 77ef13e. Took over 2.5 years for someone to run into this case!

Member

headius commented Nov 21, 2017

@kares I went ahead with it because everything JI-related looked ok.

I also figured out this was probably introduced when you cleaned up the RaiseException nonsense in getProxyClassOrNull in 77ef13e. Took over 2.5 years for someone to run into this case!

@headius headius closed this in 8d5b2ca Nov 21, 2017

@kares

This comment has been minimized.

Show comment
Hide comment
@kares

kares Nov 21, 2017

Member

heh, time sure flies and bugs prevail. makes sense - thanks for the fix 💜

Member

kares commented Nov 21, 2017

heh, time sure flies and bugs prevail. makes sense - thanks for the fix 💜

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment