简体   繁体   English

脚本Java:从外部文件导入类

[英]Scripting java : import a class from an external file

I want to import a class that I already write in an external folder, for example : My class Example.java that is located in c:\\class\\Example.java to my script like using 我想将已经在外部文件夹中编写的类导入,例如:将位于c:\\class\\Example.javaExample.java导入到脚本中,例如使用

var importedClass = new JavaImporter("c:\\class\\Example.java");

or 要么

importClass("c:\\class\\Example.java");

this is in a script for ScriptEngine rhino 这是在ScriptEngine rhino的脚本中
how can I do that ??? 我怎样才能做到这一点 ???

I understand that you want to: 我了解您要:

  1. Compile a Java source file 编译Java源文件
  2. Load the compiled code 加载编译后的代码
  3. Use the resultant class in some JavaScript 在某些JavaScript中使用结果类

The javax.tools package provides a mechanism for compiling code, though if you're not running in a JDK, ToolProvider.getSystemJavaCompiler() will return null and you'll have to rely on some other compilation mechanism (invoking an external compiler; embedding the Eclipse compiler; etc.). javax.tools包提供了一种用于编译代码的机制,尽管如果您不在JDK中运行,则ToolProvider.getSystemJavaCompiler()将返回null并且您将不得不依靠其他一些编译机制(调用外部编译器;嵌入) Eclipse编译器;等等)。

Java bytecode ( .class binaries) can be loaded at runtime via ClassLoader s. Java字节码( .class二进制文件)可以在运行时通过ClassLoader加载

In order for the loaded classes to be visible to your scripting engine, you'll need to provide them via the ScriptEngineManager(ClassLoader) constructor. 为了使加载的类对脚本引擎可见,您需要通过ScriptEngineManager(ClassLoader)构造函数提供它们。


EDIT: based on the requirements 编辑:根据要求

public class HelloWorld {
  public void say() {
    System.out.println("Hello, World!");
  }
}

This script just invokes the Java reflection API to load and instantiate a class HelloWorld.class from the C:\\foo\\bin directory: 该脚本仅调用Java反射API来从C:\\foo\\bin目录加载和实例化类HelloWorld.class

function classImport() {
  var location = new java.net.URL('file:/C:/foo/bin/');
  var urlArray = java.lang.reflect.Array.newInstance(java.net.URL, 1);
  urlArray[0] = location;
  var classLoader = new java.net.URLClassLoader(urlArray);
  return classLoader.loadClass("HelloWorld");
}

var myClass = classImport();

for(var i=0; i<10; i++) {
  myClass.getConstructor(null).newInstance(null).say();
}

There are more elegant ways of doing this, I'm sure. 我敢肯定,还有更优雅的方法可以做到这一点。

I would question why do this. 我会问为什么这样做。

The solutions listed here will work. 此处列出的解决方案将起作用。 The problem is going to be that: 问题将是:

  1. You will have a cobbled together solution with reflection that will be hard to troubleshoot. 您将获得一个经过拼凑的反射解决方案,这将很难解决。
  2. Are your customers Okay with patching code that is loaded at Runtime ? 您的客户可以在运行时加载补丁代码吗? Everyplace I have worked at is not. 我工作过的每个地方都不是。

If I understand you correctly, what you are actually trying to do is load Java classes so that you can (presumably) create instances, etcetera. 如果我对您的理解正确,那么您实际上要尝试的是加载Java类,以便(大概)可以创建实例等。 The term for this is dynamic loading not importing. 术语是动态加载而不是导入。

Java allows you to dynamically load bytecode files ( *.class ) using the ClassLoader.loadClass(String) method. Java允许您使用ClassLoader.loadClass(String)方法动态加载字节码文件( *.class )。 There are lots of resources on this topic; 关于这个主题有很多资源。 eg the " Class Loading " page from the JNDI tutorial. 例如,JNDI教程中的“ 类加载 ”页面。 Be prepared to spend some time getting your head around this topic. 准备花一些时间来解决这个问题。 In particular, since you are trying to load a class that is not on your application's normal classpath, you will need to create a new classloader to do this. 特别是,由于您尝试加载不在应用程序常规类路径上的类,因此您需要创建一个新的类加载器来执行此操作。 The Javadocs for the java.lang.ClassLoader class are here . java.lang.ClassLoader类的Javadocs在这里

Java source code cannot be directly loaded, but must first be compiled using a Java compiler. Java源代码无法直接加载,但必须首先使用Java编译器进行编译。 If you are using a modern JDK installation, it is possible to call the Java compiler at runtime. 如果使用的是现代JDK安装,则可以在运行时调用Java编译器。 But a JRE installation does not include a Java compiler. 但是,JRE安装不包括Java编译器。 If your platform has a Java compiler available at runtime, you can access it via the getSystemJavaCompiler() static method of the ToolProvider class. 如果您的平台在运行时提供了Java编译器,则可以通过ToolProvider类的getSystemJavaCompiler()静态方法对其进行ToolProvider Once again, calling the Java compiler from within a running Java application is complicated. 再一次,从正在运行的Java应用程序中调用Java编译器很复杂。

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

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