ab 4.10.2 nur noch JDK

Der Fallback Compiler / langtools-b*.jar wurde entfernt. Der Installer prüft nun ob das verwendete Java Home für den Server ein gültiges JDK ist.

Dieser Artikel ist damit ab Nuclos v4.10.2 nicht mehr relevant!

Nuclos Java Compiler

Der Nuclos Server braucht für die Regeln und Reports (von JasperReports) einen Java Compiler. Falls der Nuclos Server auf einem JDK läuft, wird dessen Compiler (javac) verwendet. Falls der Nuclos Server auf einem JRE läuft, wird der Compiler aus langtools-b<version>.jar benutzt.

Der Nuclos Client kommt mit einer groovy Umgebung, die in der Lage ist, groovy Code auszuführen.

Langtools

Das langtools-b<version>.jar stellen wir auf unserem Sonatype Nexus Maven Repository Server als de.novabit.langtools.b22:langtools-b22.jar zur Verfügung, es beruht aber auf den (freien) Quellen des OpenJDK langtools Projekt. Diese finden sich in einem mercurial SCM:

Diese Quellen können mit Hilfe von ant compiliert werden. Weitere Details finden Sie in dem Readme in den Repositories.

Build Langtools

Am Beispiel von Java7:

$ hg clone http://hg.openjdk.java.net/jdk7/jdk7/langtools
$ hg checkout jdk7-b147
$ cd langtools

Jetzt die Datei make/build.properties anpassen. Hier muss (mindestens) der Bootstrap Compiler angegeben werden:

boot.java.home = /usr/lib/jvm/jdk1.7.0_21

Für den Build der Java6 Langtools sollte man unbedingt einen Java6 Compiler verwenden. Ferner musste ich in make/build.properties diese Zeile anpassen (kein -Werror):
javac.lint.opts = -Xlint:all,-unchecked,-deprecation,-fallthrough,-cast,-serial

Eventuell ist es möglich, git statt hg zum Auschecken der Quellen zu verwenden, mittels git-remote-hg. Ich habe das aber bisher nicht ausprobiert.

 

Nun können die Langtools gebaut werden:

$ ant -f make/build.xml

Das fertige Jar findet sich unter dist/lib/classes.jar. Diese kann man nun (bei entsprechenden Rechten) auf den Nexus hochladen.

FAQ

Warum benutzt JasperReports nicht jdtcore-<version>.jar als Compiler?

JasperReports benutzt 'normalerweise' den Eclipse Java Compiler (jdtcore). Auf dem Server wird JasperReports solange 'massiert', bis auch dieses einen JDK Compiler schluckt (siehe org.nuclos.server.report.ejb3.ReportFacadeBean.postConstruct(), org.nuclos.server.report.ejb3.JRJavaxToolsCompiler).

Wo wird im Code eingestellt, welcher Compiler verwendet wird?

Es hängt davon ab, was org.nuclos.server.customcode.codegenerator.NuclosJavaCompilerComponent.getJavaCompilerTool() findet. Der Eclipse Compiler implementiert zwar javax.tools.JavaCompiler (siehe [http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/tree/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java?h=R3_8_maintenance]), die Frage ist aber, ob er auch von javax.tools.ToolProvider gefunden wird.

Laut Doku findet ToolProvider nur den 'fest installierten' Compiler (was aber nicht der Realität entspricht, s.o.). Um einen Compiler im Classpath zu finden schlägt die Doku die Benutzung des ServiceLoader vor:

ServiceLoader<javax.tools.JavaCompiler> greeterServices = ServiceLoader.load(javax.tools.JavaCompiler);

Entsprechend enthält der Eclipse Compiler (jdtcore/ecj) den entsprechenden Service Eintrag in

$ cat META-INF/services/javax.tools.JavaCompiler 
 org.eclipse.jdt.internal.compiler.tool.EclipseCompiler #Eclipse compiler

Die langtools haben keinen entsprechenden Eintrag.

NuclosJavaCompilerComponent erhält den JavaCompiler von einer ToolProvider Factory Method. Diese Klasse kann z.Z. den Eclipse Compiler nicht finden.

Der Server hat aber auch eine Abhängigkeit zu den OpenJDK langtools [http://openjdk.java.net/groups/compiler/] in der Version b22! Und die enthalten die Klasse com.sun.tools.javac.api.JavacTool.

 

  • Keine Stichwörter