Skip to content

Commit 925274f

Browse files
committed
[GR-18163] Implement Java.add_to_classpath (#2693)
PullRequest: truffleruby/3438
2 parents 2742327 + da633a0 commit 925274f

File tree

9 files changed

+69
-1
lines changed

9 files changed

+69
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
New features:
44

55
* Foreign strings now have all methods of Ruby `String`. They are treated as `#frozen?` UTF-8 Ruby Strings.
6+
* Add `Java.add_to_classpath` method to add jar paths at runtime (#2693, @bjfish).
67

78
Bug fixes:
89

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
slow:Java.add_to_classpath loads a jar file
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright (c) 2022, 2022 Oracle and/or its affiliates. All rights reserved. This
2+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
3+
# redistribute it and/or modify it under the terms of the:
4+
#
5+
# Eclipse Public License version 2.0, or
6+
# GNU General Public License version 2, or
7+
# GNU Lesser General Public License version 2.1.
8+
9+
require_relative '../../ruby/spec_helper'
10+
11+
guard -> { !TruffleRuby.native? } do
12+
describe "Java.add_to_classpath" do
13+
before :all do
14+
jar_dir = File.expand_path(File.dirname(__FILE__)) + '/fixtures/examplejar'
15+
bin_dir = TruffleRuby.graalvm_home + '/bin'
16+
Dir.chdir(jar_dir) do
17+
system("#{bin_dir}/javac org/truffleruby/examplejar/Example.java")
18+
system("#{bin_dir}/jar cf example.jar org/truffleruby/examplejar/Example.class")
19+
end
20+
@jar_file = jar_dir + '/example.jar'
21+
end
22+
23+
it "loads a jar file" do
24+
Java.add_to_classpath(@jar_file).should == true
25+
example_object = Java.type('org.truffleruby.examplejar.Example').new
26+
example_object.hello("Spec").should == "Hello Spec"
27+
end
28+
end
29+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.truffleruby.examplejar;
2+
3+
public class Example {
4+
5+
public String hello(String name){
6+
return "Hello " + name;
7+
}
8+
9+
}

src/main/java/org/truffleruby/interop/InteropNodes.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import org.truffleruby.language.control.RaiseException;
5555
import org.truffleruby.language.dispatch.DispatchNode;
5656
import org.truffleruby.language.library.RubyStringLibrary;
57+
import org.truffleruby.language.loader.FileLoader;
5758
import org.truffleruby.language.objects.LogicalClassNode;
5859
import org.truffleruby.shared.TruffleRuby;
5960

@@ -1767,6 +1768,27 @@ private Object javaType(String name) {
17671768
return env.lookupHostSymbol(name);
17681769
}
17691770

1771+
}
1772+
1773+
@Primitive(name = "java_add_to_classpath")
1774+
public abstract static class JavaAddToClasspathNode extends PrimitiveArrayArgumentsNode {
1775+
1776+
@TruffleBoundary
1777+
@Specialization(guards = "strings.isRubyString(path)")
1778+
protected boolean javaAddToClasspath(Object path,
1779+
@CachedLibrary(limit = "LIBSTRING_CACHE") RubyStringLibrary strings) {
1780+
TruffleLanguage.Env env = getContext().getEnv();
1781+
try {
1782+
TruffleFile file = FileLoader.getSafeTruffleFile(getLanguage(), getContext(),
1783+
strings.getJavaString(path));
1784+
env.addToHostClassPath(file);
1785+
return true;
1786+
} catch (SecurityException e) {
1787+
throw new RaiseException(getContext(),
1788+
coreExceptions().securityError("unable to add to classpath", this), e);
1789+
}
1790+
}
1791+
17701792
}
17711793
// endregion
17721794

src/main/java/org/truffleruby/language/loader/FileLoader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public Pair<Source, Rope> loadFile(String path) throws IOException {
7777
return Pair.create(source, sourceRope);
7878
}
7979

80-
static TruffleFile getSafeTruffleFile(RubyLanguage language, RubyContext context, String path) {
80+
public static TruffleFile getSafeTruffleFile(RubyLanguage language, RubyContext context, String path) {
8181
final Env env = context.getEnv();
8282
final TruffleFile file;
8383
try {

src/main/ruby/truffleruby/core/truffle/polyglot.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,10 @@ class ForeignException < Exception # rubocop:disable Lint/InheritException
535535
end
536536

537537
module Java
538+
def self.add_to_classpath(path)
539+
Primitive.java_add_to_classpath(path)
540+
end
541+
538542
def self.type(name)
539543
Truffle::Interop.java_type(name)
540544
end

test/mri/excludes/TestGc.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
exclude :test_start_immediate_sweep, "needs investigation"
1414
exclude :test_verify_internal_consistency, "needs investigation"
1515
exclude :test_gc_disabled_start, "fails on native: GR-38054"
16+
exclude :test_exception_in_finalizer_procs, "transient"

test/mri/excludes/TestThread.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@
2121
exclude :test_handle_interrupt, "needs investigation"
2222
exclude :test_ignore_deadlock, "needs investigation"
2323
exclude :test_switch_while_busy_loop, "transient"
24+
exclude :test_handle_interrupt_and_p, "transient"

0 commit comments

Comments
 (0)