Skip to content

Commit 62fa282

Browse files
committed
find gem extension classes for uri-like filenames
depending on how the load-service resolves a require ($LOAD_PATH, argument of require) it can happen that the ClassExtensionLibrary gets a uri-like searchName. in such a case it needs to be treated as absolute file so the class-name builder will try the right class-name as well. fixes #2986 Sponsored By Lookout Inc.
1 parent e237201 commit 62fa282

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

core/src/main/java/org/jruby/runtime/load/ClassExtensionLibrary.java

+15-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@
2828
package org.jruby.runtime.load;
2929

3030
import jnr.posix.JavaSecuredFile;
31+
3132
import org.jruby.Ruby;
3233

3334
import java.net.URL;
35+
import java.util.regex.Matcher;
36+
import java.util.regex.Pattern;
3437

3538
/**
3639
* The ClassExtensionLibrary wraps a class which implements BasicLibraryService,
@@ -44,6 +47,8 @@ public class ClassExtensionLibrary implements Library {
4447
private final Class theClass;
4548
private final String name;
4649

50+
private static Pattern URI_LIKE = Pattern.compile("(uri:classloader|file|jar|jar:file:uri):/?/?");
51+
4752
/**
4853
* Try to locate an extension service in the current classloader resources. This happens
4954
* after the jar has been added to JRuby's URLClassLoader (JRubyClassLoader) and is how
@@ -63,11 +68,19 @@ public class ClassExtensionLibrary implements Library {
6368
* @return a ClassExtensionLibrary that will boot the ext, or null if none was found
6469
*/
6570
static ClassExtensionLibrary tryFind(Ruby runtime, String searchName) {
71+
final boolean isAbsolute;
72+
Matcher matcher = URI_LIKE.matcher(searchName);
73+
if (matcher.matches()) {
74+
searchName = matcher.replaceFirst("");
75+
isAbsolute = true;
76+
}
77+
else {
78+
isAbsolute = new JavaSecuredFile(searchName).isAbsolute();
79+
}
80+
6681
// Create package name, by splitting on / and successively accumulating elements to form a class name
6782
String[] elts = searchName.split("/");
6883

69-
boolean isAbsolute = new JavaSecuredFile(searchName).isAbsolute();
70-
7184
String simpleName = buildSimpleName(elts[elts.length - 1]);
7285

7386
int firstElement = isAbsolute ? elts.length - 1 : 0;

test/test_load_gem_extensions.rb

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
require 'test/unit'
2+
require 'test/test_helper'
3+
require 'rbconfig'
4+
require 'jruby/path_helper'
5+
6+
class TestLoad < Test::Unit::TestCase
7+
include TestHelper
8+
9+
def setup
10+
@prev_loaded_features = $LOADED_FEATURES.dup
11+
@prev_load_path = $LOAD_PATH.dup
12+
end
13+
14+
def teardown
15+
$LOADED_FEATURES.clear
16+
$LOADED_FEATURES.concat(@prev_loaded_features)
17+
$LOAD_PATH.clear
18+
$LOAD_PATH.concat(@prev_load_path)
19+
end
20+
21+
def test_require_extension_file_via_uri_protocol
22+
require 'uri:file:./lib/ruby/shared/json/ext/parser'
23+
# just check if extension class exists
24+
JSON::Ext::Parser
25+
end
26+
27+
def test_require_extension_file_via_uri_classloader_protocol
28+
require 'uri:classloader:/lib/ruby/shared/json/ext/generator'
29+
# just check if extension class exists
30+
JSON::Ext::Generator
31+
end
32+
end

0 commit comments

Comments
 (0)