在内部编译类时,类路径无法正常工作?

Nat*_* F. 6 java compilation classpath

我正在开发一个用户可以在原始Java代码中存储插件的项目.然后我的应用程序将获取这些插件,编译它们并导入它们.这些类基于存储在我的jar中的接口.但是,当我尝试使用JavaCompiler.CompilationTask运行它时,它拒绝允许我将当前jar添加到编译器的类路径中.在这种情况下,当它试图编译它时,就好像接口不可用于实现一样.

这是我的文件的结构:

主.jar文件:

CommandProcessor.java
----------------------------------------------
package plugins;
public interface CommandProcessor {
    public String onCommand(String command);
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个加载插件的功能.

http://hastebin.com/jabacopeye.coffee(HasteBin避免过于混乱的问题)

以下是其中一个用户插件的示例:

public class MyCommand implements plugins.CommandProcessor {
    @Override
    public String onCommand(String command){
            return "this is a test";
    }
}
Run Code Online (Sandbox Code Playgroud)

每当应用程序尝试编译这个外部存储的.java文件时,它都会说"plugins.CommandProcessor"类不存在.

Sky*_*ker 3

正如你所说,

每当应用程序尝试编译此外部存储的 .java 文件时,它都会说“plugins.CommandProcessor”类不存在。

所以实际问题是

  1. 您的 jar 文件结构和 java 文件位置不匹配,因为您在外部存储了 .java 文件。在您的代码中,当task.call()调用 URLClassLoader 时,无法从"./plugins/WebC/plugins/"位置加载文件。

所以你的代码无法继续执行以下操作

 if (task.call()) {
     URLClassLoader classLoader = new URLClassLoader(new URL[]{new File("./plugins/WebC/plugins/").toURI().toURL()});
     Class<?> loadedClass = classLoader.loadClass(className);
     Object obj = loadedClass.newInstance();
     if (obj instanceof CommandProcessor) {
         CommandProcessor cmd = (CommandProcessor)obj;
         classLoader.close();
         return cmd;
     }else{
        classLoader.close();
     }
 }
Run Code Online (Sandbox Code Playgroud)

因此,您需要在类路径上指定 jar。

类路径上的 JAR

java编译器和运行时不仅可以在单独的文件中搜索类,还可以在JAR' archives. A JAR file can maintain its own directory structure, and Java follows exactly the same rules as for searching in ordinary directories. Specifically,目录名=包名'中搜索类。因为 JAR 本身就是一个目录,所以要在类搜索路径中包含 JAR 文件,该路径必须引用 JAR 本身,而不仅仅是包含 JAR 的目录。这是一个非常常见的错误。假设我在目录 /myclasses 中有一个 JAR myclasses.jar。为了让 Java 编译器在这个 jar 中查找类,我们需要指定:

javac -classpath /myclasses/myclasses.jar ...
Run Code Online (Sandbox Code Playgroud)

不仅仅是 myclasses 目录。

多类搜索目录

在上面的示例中,我们告诉 javac 一次仅搜索一个目录。实际上,您的类搜索路径将包含大量目录和 JAR 档案。javac 和 java 的 -classpath 选项允许指定多个条目,但请注意,Unix 和 Windows 系统的语法略有不同。在 Unix 上,我们会这样做:

javac -classpath dir1:dir2:dir3 ...
Run Code Online (Sandbox Code Playgroud)

而在 Windows 上我们有:

javac -classpath dir1;dir2;dir3 ...
Run Code Online (Sandbox Code Playgroud)

差异的原因是 Windows 使用冒号 (:) 字符作为文件名的一部分,因此它不能用作文件名分隔符。当然,目录分隔符也不同:Unix 中的正斜杠 (/) 和 Windows 中的反斜杠 ()。

资源位置:

  1. Java 忽略类路径
  2. 类路径和多类搜索目录中的 JAR