簡體   English   中英

如何編譯依賴於運行時的.java?

[英]How to compile .java with dependencies on runtime?

我有很多.java文件,需要導入另一個.java文件...

像這樣:

import package.c;

public class A {

  // do whatever that needs package.c
}

但是我只有package.c.java

當我嘗試使用Java編譯器或我知道的其他任何東西進行編譯時,總是會遇到這些錯誤

錯誤:程序包<-package->不存在

或類似的東西:

錯誤:找不到符號

我不能編譯A.java因為需要C.class不能編譯的原因需要一個又一個,有人知道我應該怎么辦?

.java不需要依賴項時,一切正常,在這種情況下,Java Compiler表現良好。

也許GetStarted鏈接可以解決我的問題,但是我找不到解決方法。

[編輯]這是我的編譯器代碼:

    File sourceDir = new File(source);
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, Locale.getDefault(), null);
    List<JavaFileObject> javaObjects = scanRecursivelyForJavaObjects(sourceDir, fileManager);
    System.out.println(javaObjects.size());
    if (javaObjects.size() == 0) {
        throw new CompilationError("There are no source files to compile in " + sourceDir.getAbsolutePath());
    }
    String[] compileOptions = new String[]{"-d", sourceDir.getAbsolutePath()};
    Iterable<String> compilationOptions = Arrays.asList(compileOptions);

    CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compilationOptions, null, javaObjects);

    if (!compilerTask.call()) {            
        for (Diagnostic<?> diagnostic : diagnostics.getDiagnostics()) {
            System.err.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
        }
        throw new CompilationError("Could not compile project");
    }

我在其中給出一個路徑,並在其中找到所有.java文件,然后將它們添加到列表中並嘗試同時進行編譯。

javaDoc有點有用: https ://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html

主要是這樣的:

JavaCompiler.CompilationTask getTask(寫出,JavaFileManager fileManager,DiagnosticListener診斷偵聽器,Iterable選項,Iterable類,Iterable編譯單元)

參數:

  • out-編寫器,用於編譯器的其他輸出; 如果為null,則使用System.err
  • fileManager-文件管理器; 如果為null,則使用編譯器的標准文件管理器
  • diagnosticListener-診斷偵聽器; 如果為null,則使用編譯器的默認方法報告診斷
  • classes-要通過注釋處理處理的類的名稱,null表示沒有類名稱
  • options-編譯器選項,null表示沒有選項
  • CompilationUnits-要編譯的編譯單元,null表示沒有編譯單元

所以...

我跟着開了一個項目

package compileTest1;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;


public class MyCompiler {

private File classesDir;
private File sourceDir;

public void loadClassesFromCompiledDirectory() throws Exception {
    new URLClassLoader(new URL[]{classesDir.toURI().toURL()});
}

public void compile() throws Exception {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, Locale.getDefault(), null);
    List<JavaFileObject> javaObjects = scanRecursivelyForJavaObjects(sourceDir, fileManager);

    if (javaObjects.size() == 0) {
        throw new Exception("There are no source files to compile in " + sourceDir.getAbsolutePath());
    }
    String[] compileOptions = new String[]{"-d", classesDir.getAbsolutePath()} ;
    Iterable<String> compilationOptions = Arrays.asList(compileOptions);

    CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compilationOptions, null, javaObjects) ;

    if (!compilerTask.call()) {
        for (Diagnostic<?> diagnostic : diagnostics.getDiagnostics()) {
            System.err.format("Error on line %d in %s", diagnostic.getLineNumber(), diagnostic);
        }
        throw new Exception("Could not compile project");
    }
}

private List<JavaFileObject> scanRecursivelyForJavaObjects(File dir, StandardJavaFileManager fileManager) {
    List<JavaFileObject> javaObjects = new LinkedList<JavaFileObject>();
    File[] files = dir.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            javaObjects.addAll(scanRecursivelyForJavaObjects(file, fileManager));
        }
        else if (file.isFile() && file.getName().toLowerCase().endsWith(".java")) {
            javaObjects.add(readJavaObject(file, fileManager));
        }
    }
    return javaObjects;
}


private JavaFileObject readJavaObject(File file, StandardJavaFileManager fileManager) {
    Iterable<? extends JavaFileObject> javaFileObjects = fileManager.getJavaFileObjects(file);
    Iterator<? extends JavaFileObject> it = javaFileObjects.iterator();
    if (it.hasNext()) {
        return it.next();
    }
    throw new RuntimeException("Could not load " + file.getAbsolutePath() + " java file object");
}

public File getClassesDir() {
    return classesDir;
}

public void setClassesDir(File classesDir) {
    this.classesDir = classesDir;
}

public File getSourceDir() {
    return sourceDir;
}

public void setSourceDir(File sourceDir) {
    this.sourceDir = sourceDir;
}
}

來自https://github.com/ishubin/blogix/blob/master/src/main/java/net/mindengine/blogix/compiler/BlogixCompiler.java

主要方法是:

public static void main(String[] args) {
    MyCompiler compiler = new MyCompiler();
    compiler.setClassesDir(new File(".")); 
    compiler.setSourceDir(new File("C:\\Users\\...\\workspace\\compileTest\\src\\objectA"));
    try {
        compiler.compile();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

ObjectA在他的c中得到了ObjectB,所以我們知道A依賴於B, 以確保我嘗試在cmd中將ObjectA與javac進行編譯並出現錯誤

我在cmd中遇到的錯誤: img1

項目的結構: img2

還有一件事,我將classesDir設置為路徑為“。”的文件。 因此,已編譯的Java文件的.class文件將存儲在項目的bin文件夾中。

當.java文件位於兩個不同的軟件包中時,也可以找到工作: img3

我所做的唯一更改是將classesDir值更改為->“ ... \\ compileTest \\ bin”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM