在 Java 中调用 ImportClass 6
Invoking ImportClass in Java 6
我正在做一个项目,该项目需要从一段 Java 脚本中调用 Java class,该脚本由另一段 Java 执行代码。它最初在 Java 7.51 中工作,但它也需要在 Java 1.6 中工作。0_27 但失败并显示 function importclass must be called with a class
错误消息。
这两个 JAR 是使用 Export > JAR 命令通过 Eclipse Indigo 生成的。
我创建了一个简单的 MCVE,如下所示来演示该问题。使用以下命令行执行的堆栈跟踪...
java -cp Sanity.jar;SanityCheck.jar -jar SanityCheck.jar
...如下:
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: Function importClass must be called with a class; had "[JavaPackage com.sanity.Sanity]" instead. (<Unknown source>#1) in <Unknown source> at line number 1
at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
at javax.script.AbstractScriptEngine.eval(Unknown Source)
at com.sanity.SanityCheck.<init>(SanityCheck.java:22)
at com.sanity.SanityCheck.main(SanityCheck.java:52)
Exception in thread "main" java.lang.NullPointerException
at com.sanity.SanityCheck.invoke(SanityCheck.java:31)
at com.sanity.SanityCheck.main(SanityCheck.java:53)
谁能看出我哪里出错了?
Sanity.java(在自己的同名 JAR 中)
package com.sanity;
public class Sanity {
public Sanity() {}
public void doCheck() {
System.out.println("Sanity Check Passed!");
}
}
SanityCheck.java(在自己的同名 JAR 中)
package com.sanity;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class SanityCheck {
private Invocable invoker;
public SanityCheck(String script) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
engine.eval(script);
invoker = (Invocable) engine;
} catch (ScriptException e) {
e.printStackTrace();
}
}
public void invoke() {
try {
invoker.invokeFunction("run");
} catch (ScriptException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("Sanity.js")));
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
reader.close();
SanityCheck check = new SanityCheck(builder.toString());
check.invoke();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sanity.js
importClass(Packages.com.sanity.Sanity);
function run() {
var sanObj = new Sanity();
sanObj.doCheck();
}
好消息:问题与您的 Java 或 Java 脚本代码无关。它与命令的效果有关:
java -cp [...] -jar <jar-file>
执行该命令时,忽略 -cp
参数,<jar-file>
用作 整个 类路径。
从 -jar
选项的 Java 6 documentation 到 java
工具:
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
所以你的命令的一个版本是:
java -cp Sanity.jar;SanityCheck.jar com.sanity.SanityCheck
我使用以下目录结构复制了您的示例,没有修改您的代码:
Sanity.js
com/
sanity/
Sanity.java
SanityCheck.java
... 然后 运行 从顶级目录执行以下命令:
$ /usr/lib/jvm/java-1.6.0-openjdk-amd64/bin/javac com/sanity/*.java && /usr/lib/jvm/java-1.6.0-openjdk-amd64/bin/java -classpath . com.sanity.SanityCheck
...并得到了
Sanity Check Passed!
错误归因于从 Java 脚本调用的 JAR 文件是针对 Java 7 而不是 Java 6 编译的。尝试 运行 Eclipse 中的一个主要方法很快揭示了这一点。
快速重新编译 JAR 文件,现在可以使用了。
我正在做一个项目,该项目需要从一段 Java 脚本中调用 Java class,该脚本由另一段 Java 执行代码。它最初在 Java 7.51 中工作,但它也需要在 Java 1.6 中工作。0_27 但失败并显示 function importclass must be called with a class
错误消息。
这两个 JAR 是使用 Export > JAR 命令通过 Eclipse Indigo 生成的。
我创建了一个简单的 MCVE,如下所示来演示该问题。使用以下命令行执行的堆栈跟踪...
java -cp Sanity.jar;SanityCheck.jar -jar SanityCheck.jar
...如下:
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: Function importClass must be called with a class; had "[JavaPackage com.sanity.Sanity]" instead. (<Unknown source>#1) in <Unknown source> at line number 1
at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
at com.sun.script.javascript.RhinoScriptEngine.eval(Unknown Source)
at javax.script.AbstractScriptEngine.eval(Unknown Source)
at com.sanity.SanityCheck.<init>(SanityCheck.java:22)
at com.sanity.SanityCheck.main(SanityCheck.java:52)
Exception in thread "main" java.lang.NullPointerException
at com.sanity.SanityCheck.invoke(SanityCheck.java:31)
at com.sanity.SanityCheck.main(SanityCheck.java:53)
谁能看出我哪里出错了?
Sanity.java(在自己的同名 JAR 中)
package com.sanity;
public class Sanity {
public Sanity() {}
public void doCheck() {
System.out.println("Sanity Check Passed!");
}
}
SanityCheck.java(在自己的同名 JAR 中)
package com.sanity;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class SanityCheck {
private Invocable invoker;
public SanityCheck(String script) {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
engine.eval(script);
invoker = (Invocable) engine;
} catch (ScriptException e) {
e.printStackTrace();
}
}
public void invoke() {
try {
invoker.invokeFunction("run");
} catch (ScriptException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("Sanity.js")));
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
reader.close();
SanityCheck check = new SanityCheck(builder.toString());
check.invoke();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sanity.js
importClass(Packages.com.sanity.Sanity);
function run() {
var sanObj = new Sanity();
sanObj.doCheck();
}
好消息:问题与您的 Java 或 Java 脚本代码无关。它与命令的效果有关:
java -cp [...] -jar <jar-file>
执行该命令时,忽略 -cp
参数,<jar-file>
用作 整个 类路径。
从 -jar
选项的 Java 6 documentation 到 java
工具:
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
所以你的命令的一个版本是:
java -cp Sanity.jar;SanityCheck.jar com.sanity.SanityCheck
我使用以下目录结构复制了您的示例,没有修改您的代码:
Sanity.js
com/
sanity/
Sanity.java
SanityCheck.java
... 然后 运行 从顶级目录执行以下命令:
$ /usr/lib/jvm/java-1.6.0-openjdk-amd64/bin/javac com/sanity/*.java && /usr/lib/jvm/java-1.6.0-openjdk-amd64/bin/java -classpath . com.sanity.SanityCheck
...并得到了
Sanity Check Passed!
错误归因于从 Java 脚本调用的 JAR 文件是针对 Java 7 而不是 Java 6 编译的。尝试 运行 Eclipse 中的一个主要方法很快揭示了这一点。
快速重新编译 JAR 文件,现在可以使用了。