Utilizar packages en grails… una necesidad?

Todos sabemos que en Java es una muy buena práctica la utilización de packages, a tal punto que para casi todo programador de Java es casi una obligatoriedad.

El concepto de package en si es muy bueno, casi todos los lenguajes modernos lo tienen de una u otra manera, con un nombre u otro. Se utilizan para evitar coliciones de nombres entre diferentes espacios de nombres.

De tal manera, que en el package paypal puede existir la clase Payment y en el package AlertPay tener otra clase con el mismo nombre Paypal sin ninguna relación con la anterior y cohexistir en el mismo proyecto. Cuando hay una duda (ambiguedad) sobre que clase se esta utilizando basta con escribir el nombre entero de la clase, incluido el package a la que pertenece y listo.

Diciendo esto cualquiera podria ver que tienen cierta utilidad especialmente cuando se comienzan a mezclar codigos desarrolaldos en diferentes lugares (ala plugins) en un mismo proyecto y no se puede tener control sobre que dos desarrolladores no elijan nombres que entren en conflicto.

¿Pero que sucede con grails? Desde la versión 1.2.0 cuando se crea cualquier artefact (ya sea un controller, un dominio, un servicio, etc) y no se le especifica un package, aparece un warning diciendo que es aconsejable utilizar siempre un package al cual hay que contestar con yes, para poder seguir adelante.

Eso es algo bueno, pero por la forma en que funciona Grails los packages pierden un poco su sentido. No pueden haber dos clases de Dominio, ni dos clases Controllers que tengan el mismo nombre aunque esten definidas en packages diferentes! Se entiende esto dado que Grails utiliza los nombres de las cases para su “Convention Over Configuration” y de esa manera mapear facilmente los dominios a tablas con GORM, o las urls para acceder a los Controllers. (Aclaro que lo entiendo, y seguramente hay implicancias ténicas para que sea así, pero me gustaría se le encontrara alguna vuelta)

Mi caso puntual, que me motivo a escribir este post, es que estaba realizando un plugin para realizar pagos que tenía una clase de dominio llamada Payment, y debía utilizar este plugin en un proyecto que utiliza el plugin de Paypal el cual también tiene una clase de dominio llamada Payment.

Al incluir los dos plugins en un mismo proyecto y ejecutar la aplicación se genera el siguiente error:


org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.DuplicateMappingException: duplicate import: Payment refers to both com.soluciones3f.tpv.Payment and org.grails.paypal.Payment (try using auto-import="false")

No investigaré como resolver este problema, simplemente cambiaré el nombre de mi clase para salir del paso y continuar sin problemas. Pero en todo caso es un problema latente que me gutaría encontrarle alguna solución.zorb ball for sale

Esto llevaría a pensar que, si igualmente voy a tener colision de nombres entre paquetes, ¿para que usar packages? El problema es que a veces queremos usar packages para order el código (dado que para usar packages se crean directorios.. esto lo ordena un poco y evita tener un unico directorio que mezcla Exceptions, Strategies, Utilites, etc en una sopa indistinguible) pero si alguna de estas clases que SI pertenecen a un package necesita usar una clase de dominio, que por lo que dije antes decidí no poner en un package… ahí esta nuevamente el problema.

Grails, o groovy si vamos al caso, heredan la limitación de Java de no poder hacer un import del package (default). Aquel package al que van a parar todas las clases sin package. En consecuencia no tengo forma de usarlas. Entonces, nuevamente, es muy recomendable usar siempre packages a pesar de que grails le quite un poco de sentido.

Por lo pronto, recomiendo ponerle package a todo, ya que tal vez nos puede ahorrar un dolor de cabeza si despues aparece un package que necesita usar lo que ya habia hecho antes, y si bien voy a tener que seguir coordinándome con el resto del universo para no tener dos clases con el mismo nombre, el esfuero que representa usar packages no es tan grande como para no hacerlo y desear que algún día se resuelva este problema.


Discussion Area - Leave a Comment