views:

63

answers:

2

I'm looking for a converter to make a reflection-style Java code from a normal Java code. I'm doing this to prevent exceptions like NoClassDefFoundError (I want to be dependent to a class, but I want Java to simply ignore the code if the library I'm using doesn't have that dependency class).

I expect converter like this:

initial code:

com.foo.MyClass myClass = new com.foo.MyClass()
myClass.meth1();

after conversion:

Object myClass = Class.forName("com.foo.MyClass").newInstance();
myClass.getMethods("meth1").invoke(myClass);
+1  A: 

You should try to avoid the use of reflection in your java code as much as you can. You can use other approaches, like the one suggested by , @mwittrock to avoid getting those NoClassDefFoundError.

You might be able to solve a problem using reflection, but you're likely to introduce new ones in your design. Consider the performance cost as well as the verbosity of the reflection code.

The core reflection facility was originally designed for component-based application builder tools... There are a few sophisiticated applications that require reflection. Examples include class browsers, object inspectors, code analysis tools, and interpretive embedded systems... if you have any doubt as to whether you application falls into one of these categories, it probably doesn't.

Joshua Bloch, "Effective Java", 2nd Edition.

StudiousJoseph
A: 

This might be a technically possible approach, but like other posters, I urge you to consider if this is the right way to solve your problem (and you've asked how to implement this solution rather than how to solve your original problem, so I can't really tell you if you're on the right track or not).

Are you perhaps interested in optionally depending on a library but not forcing your clients to provide it? Depending on your build system, this isn't that hard to accomplish. Maven, for example, allows you to specify a dependency as <scope>optional</scope>, which allows you to compile code against it but doesn't include it as a transitive dependency.

That being said, it is indeed possible to optionally depend on certain libraries and to take an alternate route if they're not available. In my experience, this is most easily done by hiding the details behind an interface.

As an example, I have a ProfilingAdvisor interface that works with an AspectJ aspect to profile methods I've marked with a custom annotation. I have a rudimentary implementation of this interface called SimpleProfilingAdvisor, which has no external dependencies. I have a more detailed implementation that uses the Java Simon library for additional information, called SimonProfilingAdvisor.

If clients choose to include the Java Simon library, they get the "better" implementation. If they choose not to, the "base" approach is implemented (which in your case may be to do nothing at all).

My code always operates to the interface, ProfilingAdvisor, but when instantiating the instance variable of this type, I have to determine whether the optional Simon library is on the classpath:

    private ProfilingAdvisor advisor;
    /* ... */
    try {
        Class.forName("org.javasimon.SimonManager");
        this.advisor = new SimonProfilingAdvisor();
    } catch (ClassNotFoundException classNotFoundException) {
        this.advisor = new SimpleProfilingAdvisor();
    }

One last point. While you can determine a class's existence using reflection as you're suggesting, I can't think of anything you're gaining by making reflective method accesses to it after instantiation, and you're effectively bypassing the compiler's ability to so much as check your spelling on method names, etc.

At the least, you should be working with a build system that allows you to compile against a library at compile-time but not necessarily include it in your distribution later (e.g., Maven).

RonU