2017-02-12 5 views
0

Ich habe eine Menge von .java Dateien, die eine andere .java Datei ...Wie kompiliere .java mit Abhängigkeiten zur Laufzeit?

So etwas importieren müssen:

import package.c; 

public class A { 

    // do whatever that needs package.c 
} 

Aber ich nur die package.c.java haben.

error: cannot find symbol

ich nicht kompilieren kann A.java weil Bedarf:

Wenn ich versuche, mit Java-Compiler oder irgendetwas anderes zu kompilieren, was ich weiß, ich diese Fehler

error: package <-package-> does not exist

Oder so etwas wie immer bekam C.class das kann nicht kompiliert werden, weil ich ein anderes brauche, jemand weiß, was soll ich tun?

Alles ist in Ordnung, wenn die .java Abhängigkeiten nicht benötigt, in diesen Fällen Java Compiler gut tun.

Vielleicht GetStarted Link könnte mein Problem lösen, aber ich kann keinen Weg finden, dies zu tun.

[EDIT] Das ist mein Compiler Code:

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"); 
    } 

, wo ich einen Weg geben und alle .java-Dateien in dort finden, sie in einer Liste hinzufügen und versuchen, alle zur gleichen Zeit zu kompilieren.

+0

zeigen Sie die Befehlszeile, die Sie verwenden, um Ihren Code zu kompilieren – MeBigFatGuy

+0

Kompilieren Sie alle Dateien gleichzeitig? – chrylis

+1

Sie müssen die Abhängigkeiten zur Kompilierzeit im Klassenpfad verfügbar haben, entweder als Quelle, kompiliert als Klassendateien oder verpackt in einer Jar-Bibliothek – MadProgrammer

Antwort

0

Javadoc- war ein wenig nützlich: https://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html

mainlly dies:

JavaCompiler.CompilationTask getTask (Writer out, JavaFileManager Dateimanager, DiagnosticListener diagnosticListener, Iterable Optionen, Iterable Klassen, Iterable compilationUnits)

Parameter:

  • out - ein Writer für zusätzliche Ausgabe vom Compiler; Verwenden Sie System.err wenn Null
  • fileManager - ein Dateimanager; wenn Null, verwende den Standard-Dateimanager des Compilers
  • diagnosticListener - ein Diagnose-Listener; Wenn null die Standardmethode der Compiler für die Diagnose
  • Klassen Berichterstattung - Namen von Klassen durch Annotation Verarbeitung verarbeitet werden, null bedeutet, dass keine Klassennamen
  • Optionen - Compiler-Optionen, bedeutet null keine Optionen
  • compilationUnits - die Kompilierungseinheiten zu kompilieren, null bedeutet keine Kompilierungseinheiten

so .....

öffnete ich ein Projekt mit dem follwing

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; 
} 
} 

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

Die wichtigste Methode ist:

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(); 
    } 
} 

Die ObjectA recived ObjectB in seiner c'tor, so dass wir wissen A abhängen von B, um sicher zu sein, dass ich versuchte, ObjectA w zu kompilieren ith javac in der cmd und bekam Fehler

die Fehler, die ich in der cmd bekam: img1

Die structur des Projekts: img2

eine weitere Sache, habe ich classesDir mit der Datei Pfad "." Daher wird die .class-Datei der kompilierten Java-Dateien im bin-Ordner des Projekts gespeichert.

Arbeit gerade auch finden, wenn die .java-Dateien in zwei verschiedenen Paketen sind: img3

die einzige Änderung, die ich in classesDir Wert tat, war zu -> "... \ compileTest \ bin"

Verwandte Themen