简体   繁体   English

从JRuby调用Java代码段?

[英]Calling Java code snippet from JRuby?

How can I call a Java code snippet from JRuby code? 如何从JRuby代码中调用Java代码段? My code snippet is really short, actually it's just a set of a few Java statements. 我的代码片段很短,实际上只是一些Java语句的集合。

Explained here on how to call existing Java code from JRuby. 这里解释如何从JRuby调用现有的Java代码。 The most basic usage: 最基本的用法:

require 'java'
java.lang.System.out.println("Hello, world!")

As a bit more complex example, if you want to import your arbitrary package (say, 'foo.bar.baz') from a JAR, you can do this: 作为更复杂的示例,如果要从JAR导入任意包(例如'foo.bar.baz'),可以执行以下操作:

require 'java'
require 'foobarbaz.jar'
def foo
  Java::Foo
end
shiny_thingy = foo.bar.baz.Thingy.new("Shiny")
shiny_thingy.shine()

If you want to evaluate a string as if it was Java, you would need to compile it first; 如果要像对待Java一样评估字符串,则需要先对其进行编译; you can use the techniques in this question , but Java generally frowns on autogenerated code, and it is not trivial to do it. 您可以在此问题中使用这些技术,但是Java通常对自动生成的代码不满意,并且这样做并不简单。 Or you can translate it into JRuby, calling Java classes as described above, and skip the compilation issue. 或者,您可以将其转换为JRuby,如上所述,调用Java类,然后跳过编译问题。

We might be able to help better if we knew what your snippet consisted of. 如果我们知道您的代码片段由什么组成,我们可能会更好地提供帮助。

EDIT: Here is the adaptation of the linked code that will instantiate an arbitrary class. 编辑:这是实例化任意类的链接代码的改编。 Be aware that it will create .class files, which is AFAIK inevitable when a compilation step is involved. 请注意,它将创建.class文件,涉及编译步骤时,这是不可避免的AFAIK。 The code assumes a subdirectory named tmp exists; 该代码假定存在一个名为tmp的子目录。 adapt to your use case. 适应您的用例。

shiny_source = <<-EOF
  package foo.bar.baz;
  public class Shiny {
    public Shiny() {
      System.out.println("I'm shiny!");
    }
  }
EOF

require 'java'
java_import javax.tools.SimpleJavaFileObject
java_import java.net.URI

class JavaSourceFromString < SimpleJavaFileObject
  def initialize(name, code)
    uri = "string:///" + name.gsub('.', '/') + Kind::SOURCE.extension
    super URI.create(uri), Kind::SOURCE
    @code = code
  end

  def getCharContent(ignore_encoding_errors)
    @code
  end
end

java_import javax.tools.ToolProvider
java_import java.io.StringWriter
java_import java.net.URL
java_import java.net.URLClassLoader

compilation_path = java.nio.file.Paths.get('tmp').to_absolute_path.to_s
jc = ToolProvider.get_system_java_compiler
raise "Compiler unavailable" unless jc

jsfs = JavaSourceFromString.new('foo.bar.baz.Shiny', shiny_source)
file_objects = [jsfs]
ccl = java.lang.Thread.current_thread.get_context_class_loader
classpath = ccl.getURLs.to_a.join(java.io.File::pathSeparator)
options = ['-d', compilation_path, '-classpath', classpath]
output = StringWriter.new
success = jc.get_task(output, nil, nil, options, nil, file_objects).call
raise output unless success

url = URL.new("file:" + compilation_path + "/")
ucl = URLClassLoader.new_instance([url].to_java(URL))
shiny_class = ucl.load_class('foo.bar.baz.Shiny')
shiny_class.new_instance

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM