Skip to content
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

@javalovercn
Copy link

@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
Copy link
Member

@headius 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
Copy link
Member

@headius 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
Copy link
Member

@headius 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
Copy link
Member

@headius 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
Copy link
Member

@kares 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
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.