Java CompilationTask / ClassLoader из пользовательского определения источника не смог "вызвать" - PullRequest
0 голосов
/ 08 декабря 2018

Я пробую пример кода из [Базовое Java-программирование], том 2, глава 8, с небольшими изменениями.Первый.Я собрал intellij проект с простым классом и функцией "f ()", уже скомпилированными:

public class BasicTypes {
    public void f() {
        System.out.println("BasicTypes.f()");
    }
}

Затем у меня есть 2 класса для загрузки класса:

class StringBuilderJavaSource extends SimpleJavaFileObject {
    private StringBuilder code;

    public StringBuilderJavaSource(String className) {
        super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension),
                Kind.SOURCE);
        code = new StringBuilder();
    }

    @Override
    public CharSequence getCharContent(boolean ignoreEncodingErrors) {
        System.out.println(code);
        return code;
    }

    public void append(String s) {
        code.append(s);
        code.append('\n');
    }
}

class ByteArrayJavaClass extends SimpleJavaFileObject {
    private ByteArrayOutputStream stream;

    public ByteArrayJavaClass(String className) {
        super(URI.create("bytes:///" + className), Kind.CLASS);
        stream = new ByteArrayOutputStream();
    }

    @Override
    public OutputStream openOutputStream() {
        return stream;
    }

    public byte[] getBytes() {
        return stream.toByteArray();
    }
}

А затем основная функция:

public static void main(String args[]) {
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    final List<ByteArrayJavaClass> classFileObjects = new ArrayList<>();
    DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>();
    JavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, null, null);
    fileManager = new ForwardingJavaFileManager<JavaFileManager>(fileManager) {
        @Override
        public JavaFileObject getJavaFileForOutput(
                Location location,
                final String className,
                JavaFileObject.Kind kind,
                FileObject sibling) throws IOException {
            System.out.println("Enter getJavaFileForOutput");
            if (className.startsWith("x.")) {
                ByteArrayJavaClass fileObject = new ByteArrayJavaClass(className);
                classFileObjects.add(fileObject);
                System.out.println("Enter x");
                return fileObject;
            } else {
                System.out.println("Enter others");
                return super.getJavaFileForOutput(location, className, kind, sibling);
            }
        }
    };

    StringBuilderJavaSource source = new StringBuilderJavaSource("myFirstClass");
    source.append("package x;");
    source.append("public class myFirstClass extends " + "BasicTypes" + " {");
    source.append("    public void f(){System.out.println(\"myFirstClass.f()\");}");
    source.append("}");
    JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnosticCollector,
            null, null, Arrays.asList(source));
    Boolean result = task.call();
    if (!result) {
        System.out.println("Compilation failed");
        System.exit(1);
    }
}

Программа не может скомпилировать и печатает:

package x;
public class myFirstClass extends BasicTypes {
    public void f(){System.out.println("myFirstClass.f()");}
}

Compilation failed

Кажется, что в сбое недостаточно информации для того, чтобы я сделал тур-съемку.Так где же я ошибся в своей программе и как ее исправить?

Большое спасибо.

...