javaplayframeworkclassloaderpackageruntime-packages

Extending Default Access 3rd Party Method in Java Play Framework


So I'm using a third party library in a Play application (namely the Echo Nest Java API). There are some oversights in how some methods are exposed by the library, and I need to modify one method in particular, which involves using a constructor with default access.

I had initially thought that creating a class in the same package that extends the class that I need to modify would do the trick, but it seems Java's runtime package handling is thwarting that attempt (that is, since different classloaders are being used for the two different classes, their being in the same package is not enough). I have some notion of potentially modifying the classloader for either my subclass or the Echo Nest library, but have just about no idea how to go about doing that or whether there's a better solution available.

Any pointers in the right direction would be appreciated!


Solution

  • So it turns out the solution was to load the library class using Play's default classloader, set the constructor to be accessible, and then use newInstance() to instantiate the library class. Some code, in case any one else runs into a similar problem:

    // Use the default application classloader to load the library class
    Class artistClazz = Play.application().classloader().loadClass("com.echonest.api.v4.Artist");
    // Get the package private constructor that we need
    Constructor<Artist> constructor = artistClazz.getDeclaredConstructor(EchoNestAPI.class, Map.class);
    // Make sure it's accessible to this class
    constructor.setAccessible(true);
    return constructor.newInstance(this, (Map) mq.getObject("artist"));
    

    I'm not by any means convinced that this was the best or cleanest solution to this problem, but it minimally affected the code outside of this modified subclass so I'll probably stick to it for now.