This may be a technically feasible approach, but, like other posters, I strongly recommend that you consider whether this solves your problem correctly (and you asked how to implement this solution, and not how to solve your original problem, so I can’t tell you if you are on the right track or not).
Perhaps you are not necessarily interested in depending on the library, but not forcing your customers to provide it? Depending on your build system, this is not so difficult to accomplish. For example, Maven allows you to specify a dependency as <scope>optional</scope> , which allows you to compile code, but does not include it as a transitive dependency.
At the same time, you can apparently optionally depend on some libraries and use an alternative route if they are not available. In my experience, this is easiest to do by hiding the details behind the interface.
As an example, I have a ProfilingAdvisor interface that works with the AspectJ aspect for profile methods marked with a special annotation. I have a rudimentary implementation of this interface called SimpleProfilingAdvisor that has no external dependencies. I have a more detailed implementation that uses the Simon Java library to get more information called SimonProfilingAdvisor.
If customers prefer to include the Java Simon library, they get a "better" implementation. If they don’t want to, the “basic” approach is used (which in your case may not do anything at all).
My code always works with the ProfilingAdvisor interface, but when creating an instance of an instance variable of this type, I must determine if there is an additional Simon library in the classpath:
private ProfilingAdvisor advisor; try { Class.forName("org.javasimon.SimonManager"); this.advisor = new SimonProfilingAdvisor(); } catch (ClassNotFoundException classNotFoundException) { this.advisor = new SimpleProfilingAdvisor(); }
The last point. Although you can determine the existence of a class using reflection, as you suggest, I can’t think of anything you type by accessing it in a reflective manner after creating the instance, and you effectively bypass the compiler’s ability to check your spelling for method names and etc.
At the very least, you should work with a build that allows you to compile the library at compile time, but you don't have to include it in your distribution later (for example, Maven).