Kompilacja kodu w pamięci java w locie dla Java 5 i Java 6

Jak skompilować kod Javy z dowolnego ciągu znaków (w pamięci) w Javie 5 i Javie 6, załadować go i uruchomić na nim określoną metodę (predefiniowaną)?

Zanim to rozpalisz, przejrzałem istniejące implementacje:

  • większość opiera się na Java 6 kompilator API.
  • Ci, którzy tego nie robią, polegają na sztuczkach. Tak, sprawdziłem commons-jci. Albo jestem zbyt gęsty, aby zrozumieć, jak to działa, albo po prostu nie.]}
  • nie mogłem znaleźć, jak nakarmić kompilator mojej obecnej klasy ścieżka (która jest dość Ogromna).
  • w implementacji, która działała (w Javie 6), nie mogłem znaleźć, jak poprawnie załadować wewnętrzne klasy (lub wewnętrzne anonimowe klasy).
  • chciałbym, aby całość była w pamięci, ponieważ działa w wielu środowiskach.

Jestem pewien, że to już zostało rozwiązane, ale nie mogę znaleźć niczego, co wygląda nawet na połowę jakości produkcji w google(z wyjątkiem jci, którego, jak mówiłem wcześniej, nie udało mi się użyć).

Edytuj:

  • przejrzałem JavaAssist - potrzebuję wewnętrznych klas, obsługi języka Java 5.0 i kompilacji z całą classpath. Chciałbym również tworzyć nowe klasy w locie. I może się mylić, ale nie mogłem znaleźć, Jak to zrobić z JavaAssit.
  • jestem skłonny użyć rozwiązania opartego na systemie plików (wywołanie javac), ale nie wiem, jak rozszyfrować classpath, ani jak później załadować pliki (których nie ma w mojej classpath) specjalnym classploaderem, który może być odzyskany dla wiele inwokacji. Chociaż wiem, jak to zbadać, wolałbym gotowe rozwiązanie.

Edit2: Na razie jestem zadowolony z BeanShell "Oceń". Wygląda na to, że robi wszystko, czego potrzebuję (zdobądź ciąg znaków, oceń go w kontekście 'bieżącej' ścieżki klasowej. Brakuje mu niektórych funkcji Javy 5, ale może używać klas enums (nie definiować) i skompilowanych ' generic '(usuwać), więc powinno wystarczyć na to, co chcę.

nie chcę jeszcze oznaczyć odpowiedzi jako zaakceptowanej, ponieważ mam nadzieję na lepsze rozwiązanie.

Edit3: zaakceptowałem sugestię beanshell - to naprawdę działa cudownie.

Author: Ran Biron, 2009-03-05

6 answers

Jeśli nie jesteś całkowicie związany z kompilacją, rozwiązania takie jak Beanshell, groovy i inne języki skryptowe są łatwo osadzane (w rzeczywistości java ma wbudowaną obsługę podłączania języka skryptowego, więc Twój kod nawet nie wie, w jakim języku skrypt jest napisany)

Beanshell powinien uruchomić dowolny 100% kod java IIRC, i wierzę, że Groovy może uruchomić większość kodu java -- prawdopodobnie wszystkie.

 3
Author: Bill K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 21:08:58

JCI wygląda dobrze. Ten fragment kodu powinien być twoją bazą:

JavaCompiler compiler = new JavaCompilerFactory().createCompiler("eclipse");

MemoryResourceReader mrr = new MemoryResourceReader();
mrr.add("resource name string", yourJavaSourceString.getBytes());

MemoryResourceStore mrs = new MemoryResourceStore();

CompilationResult result = compiler.compile(sources, mrr, mrs);

// don't need the result, unless you care for errors/warnings
// the class should have been compiled to your destination dir

Jakiś powód, dla którego to nie powinno działać?


Edit: Dodano MemoryResourceStore, Aby wysłać skompilowane wyjście klasy do pamięci, tak jak wymagano.

Również ustawienie javac ustawień, takich jak classpath w Twoim przypadku, można wykonać poprzez setCustomArguments(String[] pCustomArguments) w klasie JavacJavaCompilerSettings.

 9
Author: Yuval Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 21:34:10

Możesz też sprawdzić Janino.

Z ich strony:

Janino jest kompilatorem, który odczytuje wyrażenie JavaTM, blok, ciało klasy, plik źródłowy lub zestaw plików źródłowych i generuje kod bajtowy JavaTM, który jest ładowany i wykonywany bezpośrednio. Janino nie ma być narzędziem programistycznym, ale wbudowanym kompilatorem do celów kompilacji w czasie wykonywania, np. JSP.

Http://www.janino.net/

Obecnie używam go w dość dużym projekcie o krytycznym znaczeniu i działa dobrze

 6
Author: Bill Rawlinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 21:32:06

Javassist może Cię zainteresować

 1
Author: Maurice Perry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 20:49:50

Uruchom wewnątrz kontenera internetowego, takiego jak Tomcat, i najpierw Wygeneruj stronę JSP, a następnie ją wywołaj.

Pozwala to również pozbyć się starych definicji klas przez zwykłe nadpisanie strony JSP zamiast powolnego uruchamiania programu classloader.

Czy wymóg "in-memory" wynika z szybkości czy z braku zmiany bazy kodu?

 0
Author: Thorbjørn Ravn Andersen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 21:39:35

ECJ Eclipse Java Compiler

Eclipse dostarcza i używa własnego kompilatora, który nie jest javac

  • kompilator Eclipse jest używany wewnątrz IDE (Eclipse)
  • kompilator Eclipse może być również używany jako czysty kompilator wsadowy poza zaćmieniem

Skompiluj plik źródłowy

$ java -jar ecj-3.5.2.jar HelloWorld.java

 0
Author: stokito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-13 18:04:51