2017-02-12 4 views
0

У меня есть много .java файлов, которые необходимо импортировать другой файл .java ...Как скомпилировать .java с зависимостями от времени выполнения?

что-то вроде этого:

import package.c; 

public class A { 

    // do whatever that needs package.c 
} 

Но у меня только package.c.java.

Когда я пытаюсь скомпилировать с помощью Java Compiler или что-нибудь еще, что я знаю, я всегда получал эти ошибки

error: package <-package-> does not exist

Или что-то вроде:

error: cannot find symbol

Я не могу скомпилировать A.java потому необходимость C.class, которые не могут быть скомпилированы, требуют другого, кто-то знает, что мне делать?

Все нормально, когда .java не нуждается в зависимостях, в этом случае Java Compiler преуспевает.

Может быть, ссылка GetStarted может решить мою проблему, но я не могу найти способ сделать это.

[EDIT] То есть мой код компилятора:

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 там, добавив их в список и пытается собрать все одновременно.

+0

показать командную строку, которую вы используете для компиляции кода. – MeBigFatGuy

+0

Скомпилировать все файлы одновременно. – chrylis

+1

Вам нужно будет иметь зависимости, доступные во время компиляции в пути к классам, либо как источник, скомпилированный как файлы классов, либо упакованные в библиотеку Jar. – MadProgrammer

ответ

0

JavaDoc был немного полезным: https://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html

mainlly это:

JavaCompiler.CompilationTask getTask (Writer из, JavaFileManager FileManager, DiagnosticListener DiagnosticListener, Iterable варианты, Iterable классы, Iterable compilationUnits)

Параметры:

  • out - a Writer для дополнительного вывода из компилятора; используйте System.err, если null
  • fileManager - файловый менеджер; если null использовать стандартный файловый менеджер компилятора
  • diagnosticListener - диагностический прослушиватель; если нуль использовать метод компилятора по умолчанию для отчетов Diagnostics
  • классов - имена классов, подлежащая обработке путем обработкой аннотаций, нуль означает отсутствие имен классов
  • опции - опции компилятора, нуль не означает, что никаких опций
  • compilationUnits - компиляция единицы для компиляции, null означает отсутствие единиц компиляции

так .....

Я открыл проект с 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; 
} 
} 

взял из 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 RECIVED ObjectB в его c'tor, поэтому мы знать A зависит от B, , чтобы убедиться, что я попытался выполнить ObjectA w Ith JAVAC в ЦМД и получил ошибки

ошибки, которые я получил в CMD: img1

Структур проекта: img2

еще одна вещь, я поставил classesDir в файл с дорожка "." поэтому файл .class скомпилированных java-файлов будет сохранен в папке bin проекта.

работа просто найти и когда .java файлы находятся в двух различных пакетов: img3

единственное изменение, которое я сделал в стоимости classesDir к -> "... \ compileTest \ Bin"

Смежные вопросы