Monday, January 7, 2013

Class Instantiation via Reflection


The Problem:

Instantiate a class defined in a separate jar file that is declared default. Default classes can only be accessed by classes within the same package.


package com.xxx.SomeServiceImplementation;

import...


class SomeServiceImplementation implements SomeService {

public SomeServiceImplementation(EntityManager em) {
...
}

...




}


This scenario happened to me when I was asked to integrate a module that had its implementation classes set to default and was meant to be instantiated via Guice. The problem is that I can't use Guice as per instruction by the architect since he argues that the said project is already using EJB. In addition, I can't change the module since it was being used by another project and I don't want to create another version of it.

Solution ?

REFLECTION to the rescue.

Here's the code snippet

Class theClass = Class.forName("com.xxx.SomeServiceImplementation");
Constructor c = theClass.getConstructor(EntityManager.class);
c.setAccessible(true);
SomeService svc = (SomeService) c.newInstance(em);

Where SomeService is the interface while SomeServiceImplementation is the class that implements SomeService. SomeServiceImplementation's constructor requires an EntityManger.