Issue Details (XML | Word | Printable)

Key: JRUBY-3286
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Alex Coles
Votes: 0
Watchers: 3
Operations

If you were logged in you would be able to see more operations.
JRuby

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

Created: 06/Jan/09 09:41 AM   Updated: 05/Oct/09 03:18 PM
Return to search
Component/s: Extensions, Java Integration
Affects Version/s: JRuby 1.1.5
Fix Version/s: JRuby 1.x+

Time Tracking:
Not Specified

File Attachments: 1. Text File JRUBY-3286.patch (4 kB)

Environment:
Mac OS X 10.5.5; SoyLatte 1.0.3 i386:
java version "1.6.0_03-p3"
Java(TM) SE Runtime Environment (build 1.6.0_03-p3-landonf_19_aug_2008_14_55-b00)
Java HotSpot(TM) Server VM (build 1.6.0_03-p3-landonf_19_aug_2008_14_55-b00, mixed mode)


 Description  « Hide

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



Charles Oliver Nutter added a comment - 03/Sep/09 12:27 PM

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;
	}
}

David Calavera added a comment - 05/Sep/09 07:42 AM

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.


Charles Oliver Nutter added a comment - 06/Sep/09 01:54 AM

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.


David Calavera added a comment - 07/Sep/09 04:30 AM

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.


Charles Oliver Nutter added a comment - 05/Oct/09 03:18 PM

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.