Extending Default Access 3rd Party Method in Java Play Framework

71 views Asked by At

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!

1

There are 1 answers

0
Shane Moore On BEST ANSWER

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.