2009-08-30 14 views
0

Il y a des classes:Java StackOverflowError lors de la compilation d'une méthode clone

InterfaceInterval<C extends Comparable<C>, I extends InterfaceInterval<C, I>> extends Comparable<InterfaceInterval<C, ?>> 
AbstractInterval<C extends Comparable<C>, I extends AbstractInterval<C, I>> implements InterfaceInterval<C, I>, Serializable, Cloneable 
AbstractTimeInterval<I extends AbstractTimeInterval<I>> extends AbstractInterval<Date, I> 
SortedIntervalsList<C extends Comparable<C>, I extends AbstractInterval<C, ?>> extends ArrayList<I> 
Timeline extends SortedIntervalsList<Date, AbstractTimeInterval<?>> 

et maintenant l'ajout de cette ligne: méthode

Timeline t = (Timeline) super.clone(); 

à clone() dans la classe Timeline je reçois:

mvn -e clean compile 
The system is out of resources. 
Consult the following stack trace for details. 
java.lang.StackOverflowError 
    at com.sun.tools.javac.code.Type$WildcardType.isSuperBound(Type.java:435) 
    at com.sun.tools.javac.code.Types$1.visitWildcardType(Types.java:102) 
    at com.sun.tools.javac.code.Types$1.visitWildcardType(Types.java:98) 
    at com.sun.tools.javac.code.Type$WildcardType.accept(Type.java:416) 
    at com.sun.tools.javac.code.Types$MapVisitor.visit(Types.java:3232) 
    at com.sun.tools.javac.code.Types.upperBound(Types.java:95) 
    at com.sun.tools.javac.code.Types.adaptRecursive(Types.java:2986) 
    at com.sun.tools.javac.code.Types.adapt(Types.java:3016) 
    at com.sun.tools.javac.code.Types.adaptRecursive(Types.java:2977) 
    at com.sun.tools.javac.code.Types.adaptRecursive(Types.java:2986) 
    at com.sun.tools.javac.code.Types.adapt(Types.java:3016) 
    ... 
    at org.apache.maven.plugin.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:516) 
    at org.apache.maven.plugin.CompilerMojo.execute(CompilerMojo.java:114) 
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451) 
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558) 
    ... 16 more 

Mais, quand je commente cette ligne:

//Timeline t = (Timeline) super.clone(); 

et:

mvn compile 
... 
[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESSFUL 
[INFO] ------------------------------------------------------------------------ 
... 

puis décommenter cette ligne à nouveau:

Timeline t = (Timeline) super.clone(); 

et:

mvn compile 
... 
[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESSFUL 
[INFO] ------------------------------------------------------------------------ 
... 

Il fonctionne très bien avec peu d'aide;). Sur Eclipse, cela fonctionne aussi: /. Que devrais-je faire? Est-ce un bug de compilateur Java ou quelque chose?

The full console log.

+0

Est-ce que vous postez pas cette question l'autre jour avec un lien vers un CR ? Certaines versions de certains compilateurs ont des bogues. –

+0

Oui, dupe de: http://stackoverflow.com/questions/1352313/adaptrecursive-stackoverflowerror –

Répondre

2

Il est presque jamais une bonne idée de prendre un bogue dans le compilateur ou JVM. Vous résoudrez vos problèmes beaucoup plus rapidement si vous supposez que le problème est lié à vous et à votre code: premier, dernier et toujours. Par tous les moyens, faites une recherche dans la base de données de bogues ou Google pour voir si quelqu'un d'autre a rencontré votre problème. (C'est la première chose que je fais quand je reçois une exception.) Mais vous constaterez que la JVM a été plus longtemps et que plus d'utilisateurs exposent des bogues que votre code, il y a de fortes chances que le problème soit dans votre code ou une hypothèse erronée sur la façon dont les choses «devraient» fonctionner. Le problème est évident: vous avez une situation où clone d'une classe qui appelle une autre, qui appelle la première, qui appelle l'autre à nouveau, ajoutant des appels à la pile d'appels jusqu'à ce qu'elle déborde. Supprimer l'appel à super.clone() interrompt le cycle.

Peut-être un bon endroit pour commencer est: Pourquoi remplacer votre classe Timeline la méthode clone? Qu'est-ce que cela vous donne qu'un constructeur de copie décent ne fait pas? Peut-être que c'est vraiment un problème de conception.

+2

Err, je ne pense pas. Si vous regardez la trace de la pile (en particulier le journal complet), vous remarquerez qu'il a ce problème dans le compilateur/maven pendant qu'il essaie de compiler et maintenant pendant qu'il est en cours d'exécution. Ma supposition mal informée est que son code déclenche un cas pathologique dans le compilateur et que Maven consomme suffisamment de ressources que le compilateur ne peut pas récupérer (d'où la raison pour laquelle il "fonctionne" dans Eclipse). Le fait qu'une deuxième exécution fonctionne avec succès semblerait soutenir cette supposition. –

1

Je m'acharnerais avec duffymo - le compilateur essaye de résoudre un cycle qui ne fonctionnera pas jusqu'à ce que l'une ou l'autre classe ait déjà été compilée (ceci pourrait faire que la deuxième fois réussisse).

Prenant de plus près, celui-ci semble vraiment mauvais (notez tous les I s):

AbstractTimeInterval<I extends AbstractTimeInterval<I>> extends AbstractInterval<Date, I> 

Ok, je pense que je sais ce que vous avez essayé là et pourquoi, mais essayez de dessiner un diagramme d'héritage pour celui-là. Je pense que vous devez restructurer cela. Débarrassez-vous de cette classe (vous devez trouver un autre endroit pour les méthodes AbstractTimeInterval) et changer

Timeline extends SortedIntervalsList<Date, AbstractTimeInterval<?>> 

à

Timeline extends SortedIntervalsList<Date, AbstractInterval<Date,?>> 
Questions connexes