janvier
2007
Aujourd’hui, je me suis amusé quelque peu avec OpenJDK.
J’ai pu le compiler, sans aucune difficulté, et j’ai également pu lancer les tests qui sont donnés avec. Mais cela fut moins aisé. Mais pas impossible.
Comme vous le savez très certainement (si pas encore, lisez l’article de la rédaction: http://java.developpez.com/annonces/open-sourcing-java/ ), Sun a rendu le compilateur de java SE (javac) open source et vous permet de le compiler très aisément.
Compiler le compilateur
Pour pouvoir compiler le compilateur javac, il vous faut tout d’abord télécharger les sources.
Depuis l’EDI NetBeans, rien de plus simple. Il vous suffit de vous rendre sur le centre de mise à jour pour installer le module appelé OpenJDK. Ce module va en fait rajouter un nouvel exemple de projet, contenant les sources du compilateur Java SE.
J’ai donc installé ce module de NetBeans me permettant de créer un projet avec les sources du compilateur.
Ensuite, il suffit de faire File -> New Project -> Sample -> OpenJDK, et choisi l’endroit où mettre le projet contenant les sources du JDK. Assurez-vous que le projet soit le principal.
Une fois cela fait, il vous suffit de faire Run -> Run Main Project et le compilateur java se compile. Ce qui est intéressant à noter est qu’il se compile tout d’abord avec le JDK utilisé par défaut (il vous faut au minimum le JDK 5). Et une fois que c’est fini, il se recompile lui-même.
Il a fallu 17 secondes à mon PC pour réaliser cette opération, ce qui est tout à fait acceptable, surtout lorsque l’on sait qu’il se compile 2 fois de suite, finalement.
C’est toujours intéressant et instructif de voir ce qui se passe dans le script Ant. Car cela pourrait être instructif pour nos projets à nous.
Examinons quelque peu les 2 fichiers qui nous intéressent: le build.xml et le build.properties.
build.jdk.version = 1.7.0
build.release = ${build.jdk.version}-opensource
build.number = b00
build.user.release.suffix = ${user.name}_${build.fullversion.time}
build.full.version = ${build.release}-${build.user.release.suffix}-${build.number}
# Set jtreg.home to jtreg installation directory
# jtreg.home =
# Set test.jdk.home to baseline JDK used to run the tests
# test.jdk.home =
compiler.source.level = 1.5
On y apprend donc déjà certaines choses:
1. c’est le compilateur du JDK 7 (build 00)
2. il vous faut un compilateur JAVA 5
3. dans la version complète du compilateur figurera votre nom et la date et heure de sa compilation.
Examinons maintenant le fichier build.xml.
Il commence par définir certaines propriétés pour indiquer où se trouvent les répertoires des
sources et les classes générées, …
<property name="src" value="src"/>
<property name="src.bin" value="${src}/bin"/>
<property name="src.classes" value="${src}/share/classes"/>
<property name="build" value ="build"/>
<property name="build.bootclasses" value="${build}/bootclasses"/>
<property name="build.classes" value="${build}/classes"/>
<property name="build.gensrc" value="${build}/gensrc"/>
<property name="build.jtreg" value="${build}/jtreg"/>
<property name="dist" value="dist"/>
<property name="dist.javac" value="${dist}"/>
Ensuite, il définit un patternset. Qui pourra être réutilisé à plusieurs endroits, ce qui permet de ne pas devoir à chaque fois redéfinir la même chose. Très intéressant donc.
<patternset id="src.javac">
<include name="javax/annotation/processing/**/*.java"/>
<include name="javax/lang/model/**/*.java"/>
<include name="javax/tools/**/*.java"/>
<include name="com/sun/source/**/*.java"/>
<include name="com/sun/tools/javac/**/*.java"/>
<include name="com/sun/tools/javadoc/DocCommentScanner.java"/>
<exclude name="**/*-template.java"/>
</patternset>
Ils y indique les fichiers à inclure, et les fichiers à exclure. On remarque que les fichiers -template.java sont ignorés. On comprendra pourquoi plus loin.
<target name="prep">
<mkdir dir="${build.bootclasses}"/>
<mkdir dir="${build.classes}"/>
<mkdir dir="${dist.javac}/bin"/>
<mkdir dir="${dist.javac}/lib"/>
<tstamp>
<format property="build.time" pattern="MM/dd/yyyy hh:mm aa"/>
<format property="build.fullversion.time" pattern="MM/dd/yyyy_HH_mm"/>
</tstamp>
<property file="build.properties"/>
</target>
Cette tâche prépare les répertoires, prend la date système et la formate de 2 façons différentes, dans de nouvelles propriétés.
<mkdir dir="${build.gensrc}/com/sun/tools/javac"/>
<copy file="${src.classes}/com/sun/tools/javac/resources/version-template.java"
tofile="${build.gensrc}/com/sun/tools/javac/resources/version.java">
<filterset begintoken="$(" endtoken=")">
<filter token="JDK_VERSION" value="${build.jdk.version}"/>
<filter token="RELEASE" value="${build.release}"/>
<filter token="FULL_VERSION" value="${build.full.version}"/>
</filterset>
</copy>
après avoir créé le répertoire pour le compilateur java, le script ant va modifier le template, en remplacant dans le code source certaines String par des valeurs de propriétés.
Un find & replace en fait. Ici, il va donc ouvrir le fichier template, remplacer les occurences de ${JDK_VERSION}, ${RELEASE} et ${FULL_VERSION} par la valeur des propriétés associées, et enregistrer la version modifiée dans un autre emplacement où se trouvent les sources générées.
<!-- to compile javac, set includeAntRuntime=no to prevent javac's
own tools.jar incorrectly appearing on the classpath -->
<javac srcdir="${src.classes}:${build.gensrc}" destdir="${build.bootclasses}"
source="${compiler.source.level}" debug="true" debuglevel="source,lines"
includeAntRuntime="no">
<patternset refid="src.javac"/>
<include name="com/sun/tools/javac/resources/version.java"/>
</javac>
Voici maintenant comment compiler les sources du compilateur.
C’est très simple. On indique les 2 répertoires où se trouvent les sources, et le répertoire où se trouveront les fichiers .class.
<echo message="recompiling compiler with itself"/>
<pathconvert pathsep=" " property="src.javac.files">
<path>
<fileset dir="${src.classes}">
<patternset refid="src.javac"/>
</fileset>
<fileset dir="${build.gensrc}">
<include name="com/sun/tools/javac/resources/version.java"/>
</fileset>
</path>
</pathconvert>
ici, on va construire le chemin pour les répertoires les uns derrière les autres en les séparant par un espace.
<java fork="true"
classpath="${build.bootclasses};${src.classes}"
classname="com.sun.tools.javac.Main">
<arg value="-sourcepath"/>
<arg path="${src.classes}:${build.gensrc}"/>
<arg value="-d"/>
<arg file="${build.classes}"/>
<arg value="-g:source,lines"/>
<arg line="${src.javac.files}"/>
</java>
Et maintenant, on peut recompiler le compilateur, mais cette fois-ci en utilisant le compilateur que l’on vient de compiler.
<copy todir="${build.classes}">
<fileset dir="${src.classes}">
<include name="com/sun/tools/javac/resources/*.properties"/>
</fileset>
</copy>
On copie les fichiers properties à leur bonne place
<jar destfile="${dist.javac}/lib/javac.jar" basedir="${build.classes}">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Built-At" value="${build.time}"/>
<attribute name="Main-Class" value="com.sun.tools.javac.Main"/>
</manifest>
</jar>
et le jar est fait, avec le manifest.
J’ai donc maintenant un fichier jar qui contient un compilateur java.
Mais comment être sûr que le compilateur Java est bien compilé.
En exécutant la batterie de tests qui est livrée avec.
1 Commentaire + Ajouter un commentaire
Commentaires récents
Archives
- janvier 2012
- novembre 2010
- février 2009
- janvier 2009
- décembre 2008
- septembre 2008
- août 2008
- décembre 2007
- octobre 2007
- septembre 2007
- juillet 2007
- mai 2007
- avril 2007
- mars 2007
- février 2007
- janvier 2007
- décembre 2006
- novembre 2006
- octobre 2006
- septembre 2006
- août 2006
- juillet 2006
- juin 2006
- mai 2006
- avril 2006
- février 2006
- janvier 2006
- décembre 2005
- novembre 2005
- octobre 2005
- septembre 2005
- août 2005
- juillet 2005
- juin 2005
- mai 2005
- avril 2005
Catégories
- Certification
- Défis
- Devoxx
- Devoxx 2008
- Devoxx 2010
- Devoxx France 2012
- Divers
- Événements Java
- Fiches
- Hardware
- In English
- Java
- JavaDay 2006
- JavaFX
- JavaOne 2005
- JavaOne 2006
- JavaOne 2007
- Javapolis 2005
- Javapolis 2006
- Javapolis 2007
- JBoss
- Livres
- Mac
- NetBeans
- OpenJDK
- Pensée
- Performance
- Perles
- Sun Tech Days Paris 2007
- Traduction
>> Par exemple, des personnes comme Neal Gafter pourront faire un prototype de compilateur java pour les closures ou autres nouveautés qu’ils nous réservent.
Ce qui permettra d’avoir une meilleure idée des impacts qu’une nouvelle syntaxe peut avoir sans forcément réellement l’introduire dans le langage
a++