Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Comportement bizarre du couple eclipse+ant

6 réponses
Avatar
seb666fr2
B'jour,

Je viens vous rapporter un petit probl=E8me assez bizarre que je
viens d'avoir avec ant+eclipse, et plus pr=E9cisemment avec la t=E2che
javac lorsque celle-ci se voit adjoindre un attribut destdir. Je
pense l'avoir r=E9solu mais j'aimerais avoir votre avis sur la nature
de ce probl=E8me =E9tant donn=E9 que je n'ai rien trouv=E9 =E0 ce sujet sur
le web.

Explication:

-> probl=E8me rencontr=E9 avec :
+ Windows XP
+ java 1.6.0_05-b13
+ eclipse 3.3.2 & 3.4M6a

Soit le source suivant qui contient une *erreur volontaire* :

public abstract class Test {
public static void main(String[] pArgs) {
Test lTest =3D new Test();
}
}

Soit le script ant suivant :

<?xml version=3D"1.0"?>
<project name=3D"Test" default=3D"compile" >
<property name=3D"source" value=3D"src" />
<property name=3D"dest" value=3D"bin" />

<target name=3D"compile">
<javac srcdir=3D"${source}" destdir=3D"${dest}" listfiles=3D"on" />
</target>
</project>

l'ex=E9cution de ce script ant en dehors d'eclipse donne lui
au r=E9sultat suivant :

-------------------------------------------------------------
Buildfile: build.xml

compile:
[javac] Compiling 1 source file to bin
[javac] Test.java
[javac] Test.java:4: Test is abstract; cannot be instantiated
[javac] Test lTest =3D new Test();
[javac] ^
[javac] 1 error
BUILD FAILED
-------------------------------------------------------------

Maintenant, si j'utilise eclipse, que je cr=E9=E9 un projet Test
contenant le source Test.java, le script ant build.xml et
que je lance un build via ce script, j'obtiens la sortie suivante :

---------------------------
Buildfile: ...build.xml
compile:
BUILD SUCCESSFUL
--------------------------

Non seulement, il m'affiche un superbe BUILD SUCCESSFUL
alors qu'il y a une =E9norme erreur dans le source mais en plus
il me g=E9n=E8re un zoli Test.class dans mon dossier "bin" qui,
lorsque je l'ex=E9cute via un "java -cp bin Test" me sort :

---------------------------
Exception in thread "main" java.lang.Error: Unresolved compilation
problem:
Cannot instantiate the type Test
at Test.main(Test.java:4)
---------------------------

Apr=E8s reflexion et une bonne prise de t=EAte, je me suis rendu
compte que tout rentre dans l'ordre dans les cas suivants :

- l'attribut destdir de la t=E2che javac fait r=E9f=E9rence =E0 un
dossier diff=E9rent du "Default output folder" du projet (qui
pointe "bin" par d=E9faut).

- Le script ant "build.xml" est d=E9fini comme =E9tant le builder
du projet.

Qu'en pensez-vous ? est-ce un bug d'eclipse ? de ant ? de
java ? ou y-a-il un dysfonctionnememt entre la chaise et le
clavier ;^b ?

--
Seb

6 réponses

Avatar
jlp
B'jour,

Je viens vous rapporter un petit problème assez bizarre que je
viens d'avoir avec ant+eclipse, et plus précisemment avec la tâche
javac lorsque celle-ci se voit adjoindre un attribut destdir. Je
pense l'avoir résolu mais j'aimerais avoir votre avis sur la nature
de ce problème étant donné que je n'ai rien trouvé à ce sujet sur
le web.

Explication:

-> problème rencontré avec :
+ Windows XP
+ java 1.6.0_05-b13
+ eclipse 3.3.2 & 3.4M6a

Soit le source suivant qui contient une *erreur volontaire* :

public abstract class Test {
public static void main(String[] pArgs) {
Test lTest = new Test();
}
}

Soit le script ant suivant :

<?xml version="1.0"?>
<project name="Test" default="compile" >
<property name="source" value="src" />
<property name="dest" value="bin" />

<target name="compile">
<javac srcdir="${source}" destdir="${dest}" listfiles="on" />
</target>
</project>

l'exécution de ce script ant en dehors d'eclipse donne lui
au résultat suivant :

-------------------------------------------------------------
Buildfile: build.xml

compile:
[javac] Compiling 1 source file to bin
[javac] Test.java
[javac] Test.java:4: Test is abstract; cannot be instantiated
[javac] Test lTest = new Test();
[javac] ^
[javac] 1 error
BUILD FAILED
-------------------------------------------------------------

Maintenant, si j'utilise eclipse, que je créé un projet Test
contenant le source Test.java, le script ant build.xml et
que je lance un build via ce script, j'obtiens la sortie suivante :

---------------------------
Buildfile: ...build.xml
compile:
BUILD SUCCESSFUL
--------------------------

Non seulement, il m'affiche un superbe BUILD SUCCESSFUL
alors qu'il y a une énorme erreur dans le source mais en plus
il me génère un zoli Test.class dans mon dossier "bin" qui,
lorsque je l'exécute via un "java -cp bin Test" me sort :

---------------------------
Exception in thread "main" java.lang.Error: Unresolved compilation
problem:
Cannot instantiate the type Test
at Test.main(Test.java:4)
---------------------------

Après reflexion et une bonne prise de tête, je me suis rendu
compte que tout rentre dans l'ordre dans les cas suivants :

- l'attribut destdir de la tâche javac fait référence à un
dossier différent du "Default output folder" du projet (qui
pointe "bin" par défaut).

- Le script ant "build.xml" est défini comme étant le builder
du projet.

Qu'en pensez-vous ? est-ce un bug d'eclipse ? de ant ? de
java ? ou y-a-il un dysfonctionnememt entre la chaise et le
clavier ;^b ?

--
Seb
Quand tu affiches ton fichier build.xml dans eclipse et que tu cliques

droit et puis Run As => Ant build
qu'est ce qu'il se passe ?

Avatar
seb666fr2
jlp wrote:

Quand tu affiches ton fichier build.xml dans eclipse et que tu cliques
droit et puis Run As => Ant build
qu'est ce qu'il se passe ?


Ce que j'expliquais dans mon message précédent, c'est à dire
la sortie suivante, sans aucune indication d'erreur :
-------------------------------------------------------------
Buildfile: build.xml
build:
BUILD SUCCESSFUL
Total time: 2 seconds
--------------------------------------------------------------

Après avoir regardé d'un peu plus près, le problème vient en fait
du système de build d'eclipse et plus précisemment du compilateur
intégré au JDT qui est capable de produire des .class même lorsque
le source contient des erreurs, tel que cela est spécifié dans la
FAQ d'eclipse :

--------------------------------------------------------------------------
(http://wiki.eclipse.org/index.php?
titleúQ_How_do_I_choose_my_own_compiler%3F&redirect=no)
FAQ How do I choose my own compiler?

[...] Finally, the _JDT_compiler_can_generate_class_files_even_when
the_source_contains_compilation_errors.
----------------------------------------------------------------------------

Donc en fait, lorsqu'un script ant est lancé via l'option
Run As->Ant Build, le compilateur génère un .class - même s'il y a
des erreurs dans le source - puis la main est donné au script ant.
Le .class étant "à jour", le source n'est pas compilé et le résultat
de l'execution du script ant est un joli "BUILD SUCCESSFUL".

Pour s'appercevoir de ce comportement, il suffit de procéder ainsi :

+ un source contenant une erreur :

public class BuggedHelloWorld {
public static void main(String[] pArgs) {
System.out.printn("Hello World");
}
}

+ un script ant "build.xml" :
<?xml version="1.0"?>
<project name="BuggedHelloWorld" default="compile" basedir=".">
<property name="src-dir" value="src"/>
<property name="dest-dir" value="bin"/>
<target name="compile">
<input message="Frapper Entrée pour continuer ..."/>
<javac srcdir="${src-dir}" destdir="${dest-dir}" listfiles="on" /

</project>


+ lancer le script ant via Run As->Ant build puis lorsque la fenêtre
d'attente "Frapper Entrée pour continuer ..." apparaît, aller -à
l'aide d'un shell ou de l'explorateur- dans le répertoire de
destination des .class ("bin") pour s'appercevoir qu'un
BuggedHelloWorld.class a été généré avant même l'execution de la
cible "javac" du script ant. Un BuggedHelloWorld.class ayant été
généré, javac va considérer qu'il n'y a rien à faire et le
résultat
de ant sera BUILD SUCCESSFUL !

Remarques importantes:
1- Le fait de supprimer le .class puis de relancer Run as->Ant
build
ne provoquera pas la génération du .class et le résultat d'ant
sera BUILD FAILED avec le bon rapport d'erreur !

2- Le fait de supprimer le .class puis de forcer la modification
de
la date de dernière modification du source -en ajoutant un
espace
au début du source par exemple- provoquera le même type
d'erreur,
c'est à dire la génération d'un .class invalide, le court-
circuitage
de javac et le retour de BUILD SUCCESSFUL par ant.

Contrairement à ce que j'ai dit dans mon premier message, le fait de
définir le script ant comme premier builder (Project->Properties-
Builder->
Import->ant build file->Up) n'est pas suffisant.


En fait, la seule chose à faire pour éviter ce problème est de
spécifier dans
la cible javac du script ant un répertoire de destination différent
(build par
exemple) de celui spécifié dans l'option Project->Properties->"Default
Output
Folder" d'eclipse. Cependant, il faut garder à l'esprit que cette
méthode
n'évitera pas la création de .class invalide dans le "Default Output
Folder".


--
SeB

Avatar
Lionel
wrote:

Après avoir regardé d'un peu plus près, le problème vient en fait
du système de build d'eclipse et plus précisemment du compilateur
intégré au JDT qui est capable de produire des .class même lorsque
le source contient des erreurs, tel que cela est spécifié dans la
FAQ d'eclipse :


pure curiosité: quel est l'intérêt de passer par ant pour compiler des
classes quand on utilise un IDE ?

Avatar
jnizet
A mon avis, la raison est toute simple:

Eclipse compile la classe en erreur et crée le .class file. Mais le
compilateur d'Eclipse te signale tout de même une erreur.
Puis, tu lances ton build Ant. Ant voit que le .class existe déjà et
est plus récent que le .java correspondant. Il ne fait donc rien du
tout (considérant que c'est déjà compilé), d'où le build successfu l.
Si tu précède le build d'un clean qui efface tout le contenu du
répertoire de destination, tu verras sans doute que Ant recompile bien
le .java, et te signales bien une erreur.

Donc soit tu compiles tout avec Ant, soit tu compiles tout avec
Eclipse, mais pas les deux en même temps, puisque les deux
compilations ne fonctionnenent pas de la même manière.

JB.
Avatar
seb666fr2
Lionel a écrit:

pure curiosité: quel est l'intérêt de passer par ant pour compiler d es
classes quand on utilise un IDE ?


Entre autre parce que l'intérêt d'Ant ne réside pas uniquement dans
sa capacité à compiler des classes, et, qu'il est toujours préférabl e
de
faire confiance au mécanisme de build d'un outil standard (Ant,
make, ...),
qu'au compilateur intégré de n'importe quel IDE.

--
SeB

Avatar
seb666fr2

A mon avis, la raison est toute simple:

Eclipse compile la classe en erreur et crée le .class file.


Oui c'est ce que je disais dans mes 2 premiers messages.
Personnellement
je trouve totalement stupide qu'un compilateur génère un binaire
lorsqu'il
trouve une erreur. Enfin ceci n'engage que moi.

Mais le compilateur d'Eclipse te signale tout de même une erreur.


Oui mais toujours de façon silencieuse, et il n'y a aucun message
demandant à l'utilisateur s'il souhaite réellement lancer un script
ant lorsque des erreurs sont en "attentes".

Puis, tu lances ton build Ant. Ant voit que le .class existe déjà et
est plus récent que le .java correspondant. Il ne fait donc rien du
tout (considérant que c'est déjà compilé), d'où le build success ful.


C'est ce que j'ai expliqué dans mes deux premiers messages.

Si tu précède le build d'un clean qui efface tout le contenu du
répertoire de destination, tu verras sans doute que Ant recompile bien
le .java, et te signales bien une erreur.



Oui c'est une solution mais ça force à faire un rebuild intégrale ce
qui
est un peu lourd.

Donc soit tu compiles tout avec Ant, soit tu compiles tout avec
Eclipse, mais pas les deux en même temps, puisque les deux
compilations ne fonctionnenent pas de la même manière.


Même lorsque l'on décoche "build-automatically", le simple fait
de lancer un script Ant provoque le déclenchement du compilateur
eclipse, c'est tout de même relativement étrange comme comportement.

En fait, la seule solution pour désactiver le compilateur d'eclipse,
c'est
de désactiver le "Java Builder" du projet (Project->Properties->
builders). Cependant, cette opération n'est pas sans effet puisque
l'on
veut décocher ce builder, il est expressement indiqué, je cite :

"This is an advanced operation. Disabling a project builder can have
many side effects."

En d'autres termes, le fait de désactiver le compilateur Eclipse va
provoquer
la perte de certaines fonctionnalités.... Oui mais lesquelles ???


--
SeB