JRuby

Java extension (JAR) not required if using an absolute path

Details

  • Type: Bug Bug
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: JRuby 1.1.5
  • Fix Version/s: JRuby 1.x+
  • Labels:
    None
  • Environment:
  • Number of attachments :
    1

Description

To reproduce:

  • create a Java extension, with a class name of MyAppExtService, implementing org.jruby.runtime.load.BasicLibraryService.
  • compile and JAR the extension as my_app_ext.jar.
  • copy the JAR into the same directory (such as "lib") as the my_app.rb file that require it
  • create a my_app.rb file with the line:
    require 'my_app_ext'
  • the extension should be required
  • now change the line in my_app.rb to:
    require File.expand_path(File.join(File.dirname(_FILE_), 'my_app_ext'))

Expected behavior:

  • the extension should load

Actual behavior:

  • the extension does not load

Example of this behavior:

This commit broke the loading of the Java extensions in the DataObjects project:
http://github.com/sam/do/commit/2b86f4a5d55205192175fe06eb93706fc876146a

This commit then returns to using relative paths so that the Java extension will load:
http://github.com/sam/do/commit/f8f2083d652821ee39f06f63ab37c9b870da506

Activity

Hide
Charles Oliver Nutter added a comment -

Wow, this is goofy. Confirmed in 1.4dev that it still works like this:

~/projects/jruby ➔ javac -cp lib/jruby.jar MyAppExtService.java 

~/projects/jruby ➔ jar cf my_app_ext.jar MyAppExtService.class 

~/projects/jruby ➔ mkdir foo

~/projects/jruby ➔ mv my_app_ext.jar foo

~/projects/jruby ➔ jruby -e "require 'foo/my_app_ext'"

~/projects/jruby ➔ jruby -e "require 'foo/my_app_ext.jar'"

~/projects/jruby ➔ mv foo/my_app_ext.jar .

~/projects/jruby ➔ jruby -e "require 'my_app_ext.jar'"
hello

~/projects/jruby ➔ cat MyAppExtService.java 
import org.jruby.runtime.load.BasicLibraryService;
import org.jruby.Ruby;
import java.io.IOException;

public class MyAppExtService implements BasicLibraryService {
	public boolean basicLoad(Ruby runtime) {
		System.out.println("hello");
		return true;
	}
}
Show
Charles Oliver Nutter added a comment - Wow, this is goofy. Confirmed in 1.4dev that it still works like this:
~/projects/jruby ➔ javac -cp lib/jruby.jar MyAppExtService.java 

~/projects/jruby ➔ jar cf my_app_ext.jar MyAppExtService.class 

~/projects/jruby ➔ mkdir foo

~/projects/jruby ➔ mv my_app_ext.jar foo

~/projects/jruby ➔ jruby -e "require 'foo/my_app_ext'"

~/projects/jruby ➔ jruby -e "require 'foo/my_app_ext.jar'"

~/projects/jruby ➔ mv foo/my_app_ext.jar .

~/projects/jruby ➔ jruby -e "require 'my_app_ext.jar'"
hello

~/projects/jruby ➔ cat MyAppExtService.java 
import org.jruby.runtime.load.BasicLibraryService;
import org.jruby.Ruby;
import java.io.IOException;

public class MyAppExtService implements BasicLibraryService {
	public boolean basicLoad(Ruby runtime) {
		System.out.println("hello");
		return true;
	}
}
Hide
David Calavera added a comment -

Actually I'm not sure if this is a bug.

There are two classes that can load the jar. ClassExtensionLibrary fails because it tries to load a class into a package, in this case "foo/MyAppExtService", JarredScript also fails because it searchs for the attribute "Ruby-Init" into the jar manifest.

So a workaround, or the correct behaviour would be to move the class to a package called 'foo'. And a possible fix would be to remove the directory path to load the class when we work with jar files.

If the fix is fine I can send a patch in a while.

Show
David Calavera added a comment - Actually I'm not sure if this is a bug. There are two classes that can load the jar. ClassExtensionLibrary fails because it tries to load a class into a package, in this case "foo/MyAppExtService", JarredScript also fails because it searchs for the attribute "Ruby-Init" into the jar manifest. So a workaround, or the correct behaviour would be to move the class to a package called 'foo'. And a possible fix would be to remove the directory path to load the class when we work with jar files. If the fix is fine I can send a patch in a while.
Hide
Charles Oliver Nutter added a comment -

Ahh good point. The line between "bug" and "badly specified behavior" is pretty fine, but I think we agree something needs to be corrected here. Toss over a proposed patch and we'll see how it looks. This loading logic obviously needs to be better specified, regardless.

Show
Charles Oliver Nutter added a comment - Ahh good point. The line between "bug" and "badly specified behavior" is pretty fine, but I think we agree something needs to be corrected here. Toss over a proposed patch and we'll see how it looks. This loading logic obviously needs to be better specified, regardless.
Hide
David Calavera added a comment -

this patch just tries to load the same class without the full package name if it fails with the package name. It also adds a test case and a jar extension as a fixture.

Actually I'm not sure if this is the best solution but the documentation neither is well specified.

Show
David Calavera added a comment - this patch just tries to load the same class without the full package name if it fails with the package name. It also adds a test case and a jar extension as a fixture. Actually I'm not sure if this is the best solution but the documentation neither is well specified.
Hide
Charles Oliver Nutter added a comment -

Punting to 1.x+ again...this needs to be examined a bit better and we need to formalize the rules/guidelines for jar-based extensions and how we load them.

Show
Charles Oliver Nutter added a comment - Punting to 1.x+ again...this needs to be examined a bit better and we need to formalize the rules/guidelines for jar-based extensions and how we load them.

People

Vote (0)
Watch (3)

Dates

  • Created:
    Updated: