2015-06-24 9 views
1

Прежде всего то, что я пытаюсь достичь:
Я хочу, чтобы скомпилировать классы Java динамически в памяти во время выполнения. В основном с предоставленным Java Compiler API, который не очень большой сделки, но когда дело доходит до нескольких классов на .java-файл, я теряюсь.В памяти сборник с более чем одного класса в файле

Что я получил до сих пор:
Я сейчас работаю с InMemoryJavaCompiler, представленной в ответ на этот вопрос (Compile code fully in memory with javax.tools.JavaCompiler)

Как описано выше, составление отдельных классов на один файл не является проблемой , но я хочу иметь возможность компилировать практически все допустимые .java-файлы.

Например файл (FileOne.java) Я пытаюсь скомпилировать выглядит так:

package test; 
public class FileOne { 
    public static void main(String args[]) { 
     System.out.println("Hello, World"); 
    } 
} 
class Functions { 
    public static int test(int x) { 
     return -x; 
    } 
} 

Когда я пытаюсь скомпилировать этот файл как InMemoryJavaCompiler.compile("test.FileOne", source), я получаю исключение по случаю defineClass(...) линии в перезаписанном ClassLoader, что говорит :

java.lang.ClassFormatError: Extra bytes at the end of class file test/FileOne 

Эта проблема также существует с внутренними классами, но это всего лишь своего рода имен/вызывающей проблемы, я думаю:

java.lang.NoClassDefFoundError: test/FileOne (wrong name: test/FileOne$Functions) 
+1

У вас есть более чем 1 класс для каждого файла? Я не погружался в 'InMemoryJavaCompiler', но по умолчанию должен быть единственный класс для каждого файла. – deathangel908

+1

Как я знаю, java ограничивает общий класс для каждого файла до 1. «InMemoryJavaCompiler» должен был просто показать вам текущую позицию, поскольку я пытаюсь решить эту проблему шаг за шагом. Если есть другие способы для моего желаемого решения, я готов его отключить. – ceekay

+0

У вас есть использование муравьев? – nafas

ответ

0

Да, вы правы, что InMemoryJavaCompilation as-is available in github не работает, если класс имеет внутренние или анонимные классы. Я столкнулся с той же проблемой, которую вы описали.

После долгих поисков я нашел JSCC, который является очень полным. Благодаря verhas (имя пользователя github) для его разработки и обеспечения его доступности. Я тестировал АОК с вложенными классами, и он отлично работает. Вы можете найти код и как его использовать в Github.

https://github.com/verhas/jscc

Насколько я понял, проблема с InMemoryJavaCompilation является то, что он хранит один byte array на класс. Однако компилятор генерирует более одного класса для класса с вложенными классами или анонимными классами. В этом случае InMemoryJavaCompilation хранит только последний класс, возвращаемый компилятором, и это может быть не класс верхнего уровня. Поэтому вы можете получить java.lang.NoClassDefFoundError. АКК поддерживает Byte Array Map, чтобы сохранить скомпилированный код всех классов.

Хотя вы долго задавали этот вопрос, я надеюсь, что это поможет.