1

I have a lot of .java files that need to import another .java file...

Something like this:

import package.c;

public class A {

  // do whatever that needs package.c
}

But I only have the package.c.java.

When I try to compile Using Java Compiler or anything else that I know, i always got these errors

error: package <-package-> does not exist

Or something like:

error: cannot find symbol

I can't compile A.java because need C.class that can't be compiled cause need another one, someone know what should I do?

Everything is ok when the .java doesn't need dependencies, in these cases Java Compiler do well.

Maybe GetStarted link could resolve my problem, but i can't find a way to do this.

[EDIT] That is my 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");
    }

where I give a path and find all .java files in there , adding them in a list and trying to compile all at same time.

1 Answers1

1

javaDoc was a little bit usefull : https://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html

mainlly this :

JavaCompiler.CompilationTask getTask(Writer out, JavaFileManager fileManager, DiagnosticListener diagnosticListener, Iterable options, Iterable classes, Iterable compilationUnits)

Parameters:

  • out - a Writer for additional output from the compiler; use System.err if null
  • fileManager - a file manager; if null use the compiler's standard filemanager
  • diagnosticListener - a diagnostic listener; if null use the compiler's default method for reporting diagnostics
  • classes - names of classes to be processed by annotation processing, null means no class names
  • options - compiler options, null means no options
  • compilationUnits - the compilation units to compile, null means no compilation units

so .....

I opened a project with the 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;
}
}

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

The main method is :

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

The ObjectA recived ObjectB in his c'tor, so we know A depend on B, to be sure I tried to complie ObjectA with javac in the cmd and got errors

the errors I got in the cmd : img1

The structur of the project : img2

one more thing, I set classesDir to file with the path "." so the .class file of the compiled java files will be stored in the bin folder of the project.

work just find also when the .java files are in two different packages : img3

the only change I did was in classesDir value to -> "... \compileTest\bin"

Ofir G
  • 736
  • 6
  • 18