2008-12-27 6 views
4

Quelqu'un peut-il me dire pourquoi cette classe de domaine Grails ne compilera pas (à l'exécution)?Grails getSomething (int i) méthode ne compile pas

class Person { 
    String name 

    String getSomething(int i) { 
    } 
} 

je reçois cette erreur quand je lance avec grails run-app:

2008-12-27 15:26:33.955::WARN: Failed startup of context [email protected]{/asrs2,C:\Steve\asrs2/web-app} 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pluginManager' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException 
     at java.security.AccessController.doPrivileged(Native Method) 
     at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy:67) 
     at RunApp_groovy$_run_closure2_closure7.doCall(RunApp_groovy) 
     at Init_groovy$_run_closure6.doCall(Init_groovy:131) 
     at RunApp_groovy$_run_closure2.doCall(RunApp_groovy:66) 
     at RunApp_groovy$_run_closure2.doCall(RunApp_groovy) 
     at RunApp_groovy$_run_closure1.doCall(RunApp_groovy:57) 
     at RunApp_groovy$_run_closure1.doCall(RunApp_groovy) 
     at gant.Gant.dispatch(Gant.groovy:271) 
     at gant.Gant.this$2$dispatch(Gant.groovy) 
     at gant.Gant.invokeMethod(Gant.groovy) 
     at gant.Gant.processTargets(Gant.groovy:436) 
     at gant.Gant.processArgs(Gant.groovy:372) 
Caused by: java.lang.NullPointerException 
     at java.lang.Class.isAssignableFrom(Native Method) 
     ... 13 more 

Si je change la méthode getSomething à doSomething il fonctionne. Est-ce que getSomething(int i) est traité en quelque sorte comme une méthode de haricot?

Suivi: Ceci est un Grails bug qui sera corrigé dans 1.2.

+0

N'êtes-vous pas censé avoir un point-virgule après l'instruction: "String name;" ? – some

+0

Il est facultatif dans Groovy –

Répondre

1

J'ai conclu qu'il s'agit d'un bug avec Grails. J'ai créé GRAILS-3760 qui a été corrigé dans Grails 1.1.2.

1

Avant de répondre à la question laissez-moi vous dire mon environnement:
Grails 1.0.4
Java 1.6.0_10-bêta
Groovy 1.6 RC-1
sur une machine Windows Vista

Dans Grails, les méthodes get dynamiques sont ajoutées au moment de l'exécution pour tous les champs de la classe de domaine. Pour la classe Person mise en évidence dans la question, une méthode getName() serait ajoutée à l'exécution ce qui permettrait de l'utiliser sans la définir. Maintenant le problème, avec getSomething (int i) est que vous n'avez pas de champ appelé String quelque chose dans votre classe. Si vous essayez d'ajouter une méthode appelée getName (int i) cela fonctionnerait sans problèmes ou si vous ajoutez un champ String à alors la méthode getSomething() fonctionnerait.

J'espère que cela résout le problème pour le moment ... Je continuerais à chercher et publier des mises à jour sur le fonctionnement exact bientôt.

7

Eh bien, vous avez deux problèmes:

  1. classes de domaine dans Grails tentent de faire en sorte que chaque propriété a un getter et setter lors du démarrage. Il le fait en recherchant tous les getters, et en s'assurant qu'un setter approprié existe. Donc, si vous avez un getSomething(), vous devez avoir un setSomething (def quelque chose), même s'il n'y a pas de propriété "quelque chose" dans la classe. Vraiment, en créant la fonction getSomething(), vous avez implicite qu'il existe une telle propriété, et vous devez également créer un setSomething().

  2. Les Getters n'acceptent pas les arguments. Le vôtre fait. Maintenant, je me rends compte que vous ne pensiez pas que c'était un "getter" quand vous l'avez écrit, mais votre nom en fait un.

Meilleur pari? N'utilisez pas les préfixes "get" ou "set" ou "is", sauf si vous créez réellement une propriété complète qui peut être obtenue et définie. J'éviterais également de "trouver" dans les classes de domaine, car cela a son propre ensemble de méthodes générées.

+0

il devrait y avoir une annotation que vous pourriez ajouter pour marquer une méthode commençant par 'get' pour ne pas être une paire getter/setter. – Chii

+0

Pas d'annotations, mais vous pouvez le faire via la propriété statique "transitoires" –

+0

Ne semble pas que Grails est une application compatible avec Java puisque getSomething (int) est parfaitement valide en Java. –

4

Au lieu de définir la méthode comme ayant un type de retour, essayez en utilisant def:

class Person { 
    String name 

    def getSomething(int i) { 
     // foo 
    } 
} 

Une autre solution pourrait consister à définir something comme transitoire (à condition que vous n'avez pas réellement une propriété appelée ' quelque chose »):

class Person { 
    String name 

    static transients = ['something'] 

    String getSomething(int i) { 
     // foo 
    } 
} 
5

quelques notes ...

  • Si vous fournissez un setter, vous n'avez pas besoin de fournir un getter. Et vice versa. Ce que vous faites est en train de surcharger les méthodes d'accès par défaut que Groovy attache à votre système. Vous pouvez remplacer l'un et pas l'autre si vous le souhaitez.
  • Il n'y a pas de problème si vous faites une méthode sur votre classe de domaine commençant par 'trouver' car les méthodes de recherche dynamique sont en fait des additions de méthodes statiques (et commencent par 'findBy *').
  • La solution transitoire ne fonctionnera pas. Faire de 'quelque chose' une valeur transitoire n'aide pas le fait que vous avez un getter avec la mauvaise signature de paramètre. Même chose lorsque vous tapez dynamiquement la valeur de retour.
  • Ce n'est pas un problème pour Groovy, mais pour Grails.

Je pense que la solution est de changer le nom de votre méthode de getSomething-findSomething ou tout ce que vous voulez que cela ne va pas contre la convention. Ce qui suit fonctionne bien:

class Person { 
    String name 

    String findSomething(int i) { 
    } 
}