0

I am suddenly getting a conflict between a class in a Grails plugin and the same class in a Grails plugin.

Grails Notification plugin has a skeleton User class defined in order to provide for stand-alone plugin testing. The User class is defined with the same package as the real User class in the main app. The plugin User class is NOT published with the plugin - it is excluded from the jar. In any case, the app class should predominate, and there is no runtime warning about duplicate classes. The plugin User class is there in the plugin sources jar, however. This has always worked fine - until now.

So, not only am I mystified, I'm also worried because we also include a number of duplicatively defined utility classes that are also excluded from the plugin jars - will those also be a problem?

Important: this problem was not there yesterday! Overnight corporate security applied some updates and forced a restart on our computers, so Intellij in particular had to be reopened. A colleague can duplicate this same new behavior on his machine, so it's not a local cache problem on my computer - pointing to a common code or build problem? We are running run-app via the Intellij IDE, but invoking run-app from a cmdline exhibits the same problem.

    // This Grails debug console code
    import com.penbaymedia.jdeis5.notification.service.EmailService // just to check existence
    
    def svc = ctx.getBean('emailService')   // in Grails Notification plugin
    
    def user = User.findByUsername('jphiloon')  // User defined in main app and in plugin
    
    svc.getEmail(user)
    
    /* Responds with this result:
    groovy.lang.MissingMethodException: No signature of method: com.penbaymedia.jdeis5.notification.service.EmailService.getEmail() is applicable for argument types: (com.penbaymedia.jdeis5.domainobject.User) values: [com.penbaymedia.jdeis5.domainobject.User : 5265]
    Possible solutions: getEmail(com.penbaymedia.jdeis5.domainobject.User), getClass(), sendMail(groovy.lang.Closure)
    The following classes appear as argument class and as parameter class, but are defined by different class loader:
    com.penbaymedia.jdeis5.domainobject.User (defined by 'org.springframework.boot.devtools.restart.classloader.RestartClassLoader@1378323c' and 'sun.misc.Launcher$AppClassLoader@18b4aac2')
    If one of the method suggestions matches the method you wanted to call, 
    then check your class loader setup.
    */

/* The error shown in the application run-app console is a bit different, but unproxying the User object does not help:
2022-03-02 11:20:00,270 ERROR com.penbaymedia.jdeis5.job.AssignmentNotificationIntervalJob - No signature of method: com.penbaymedia.jdeis5.notification.service.EmailService.getEmail() is applicable for argument types: (com.penbaymedia.jdeis5.domainobject.User$HibernateProxy$hgS4G0mO) values: [<com.penbaymedia.jdeis5.domainobject.User$HibernateProxy$hgS4G0mO@9c96547>]
Possible solutions: getEmail(com.penbaymedia.jdeis5.domainobject.User), getClass(), sendMail(groovy.lang.Closure)
*/
Jay
  • 173
  • 10
  • This classloading issue does not happen when running from a war file; it has something to do with the restart class loader I think. In the above console code, if I print the classloaders for each object I get: svc: sun.misc.Launcher$AppClassLoader@18b4aac2 user: org.springframework.boot.devtools.restart.classloader.RestartClassLoader@73c242e0 – Jay Mar 02 '22 at 19:36
  • The issue has something to do with dev-tools. A similar issue is here in github: "Grails 5.0.0.M2: inconsistent classpath in multi-module project with transitive plugins? #11566". The temporary solution is to comment dev-tools out of build.gradle. Can we confirm that this problem is resolved in any Grails release > 4.0.10? – Jay Mar 04 '22 at 23:05
  • Another variation on this problem, one that does affect production code in a war file. The same situation as above, in which the plugin has a skeletal User object to facilitate stand-alone testing. This User object is not exported from the plugin - the jar has no User class in it. The main app has a full-bodied User class of the same package. In the plugin User.get(id) blows up with the "wrong class" error mentioned above. However, the code User.findByUsername(username) has no issue. What is going on here? – Jay Mar 29 '22 at 21:12

0 Answers0