Loading a Class from a String - java

I want to instantiate a class by the value of a String. I found several tutorials that show several methods for doing this. The class MUST inherit from a certain interface, ImplementMe which has a special method called runMe(). So here's what I tried:
ImplmentMe a =
(ImplementMe) ImplementMe.class
.getClassLoader()
.loadClass("my.package.IImplementedYou")
.newInstance();
a.runMe();
It works, but it's so ugly. I at least expected not needing a cast. Please tell me there is a better way.

No, there is no better way (by design). You are not supposed to do this, Java is designed as a type-safe language. However, I can understand that you sometimes need to do things like this, and for that purposes you can create a library function like this:
public <T> T instantiate(final String className, final Class<T> type){
try{
return type.cast(Class.forName(className).newInstance());
} catch(InstantiationException
| IllegalAccessException
| ClassNotFoundException e){
throw new IllegalStateException(e);
}
}
Now your client code can at least call this method without casting:
MyInterface thingy =
instantiate("com.foo.bar.MyInterfaceImpl", MyInterface.class);

Try Class.forName("my.package.IImplementedYou").

Here's how I would do it:
ImplementMe noCastNeeded =
this.getClassLoader()
.loadClass("my.package.IImplementedYou")
.asSubclass(ImplementMe.class).newInstance();
There are some Exceptions to catch but that's ok I think. :)

In all essence that is what will happen regardless of whether you're using a third party toolkit for it or not. Casting the object will inherently be mandatory unless expecting an Object. You can however make a routine which does that for you:
public <T> T instantiateObject(String name, Class<T> cls) throws Exception {
return (T) Class.forName(name).newInstance();
}
Which you can use:
AClass cls = instantiateObject("com.class.AClass", AClass.class);
But if you come this far, the String name is actually redundant (given AClass is a concrete class). You might as well:
public <T> T instantiateObject(Class<T> cls) throws Exception {
return (T) Class.forName(cls.getCanonicalName()).newInstance();
}
Which you can use:
AClass cls = instantiateObject(AClass.class);

You can shorten it a bit like
ImplementMe a = (ImplementMe) Class
.forName("my.package.IImplementedYou")
.newInstance();
but you can't get rid of the cast. There may be a way to avoid the cast, but only if you can avoid the subproblem of loading class by name.

The alternative is to use forName, but it does not get much better than what you currently have:
ImplementMe a =
(ImplementMe) Class.forName("my.package.IImplementedYou").newInstance();
a.runMe();
Indeed, forName will use getClassLoader().loadClass() behind the scenes to load the class, as you can see in the source code of Class.java.

You will need a cast, because the compiler cannot tell from the code that the object is of type ImplementMe. It thus requires the programmer to issue a cast, which will throw a ClassCastException if the object is not an ImplementMe instance.

What you have may work, but you don't have to load the class using the same classloader that loaded ImplementMe. This should work equally well:
Object newInstance = this.getClass().getClassLoader().loadClass("my.package.IImplementedYou").newInstance();
The important thing is that the classloader knows both the class file with the implementation of "my.package.IImplementedYou" and the class with the implementation of "ImplementMe".
You may explicitly check that IImplementedYou really implements ImplementMe like this:
if(newInstance instanceof my.package.IImplementedYou) {
((ImplementMe)newInstance).runMe();
}
You may also check that IImlementedYou really is implementing the interface before creating the instance:
Class c = this.getClass().getClassLoader().loadClass("my.package.IImplementedYou");
if(ImplementMe.class.isAssignableFrom(c)) {
Object newInstance = c.newInstance();
}

(MyInterface)Class.forName(className).newInstance()

Related

Add an attribute to any java exception

I would like to customize java exceptions class by adding an attribute to them. It could be as simple as the following attribute:
boolean isThisStupid;
void setIsThisStupid(boolean iValue);
boolean getIsThisStupid();
Every time I would instantiate an exception, like a NullPointerException, or an IllegalArgumentException, it would contains this attribute.
Since I do not have the source code of Java, I cannot of course edit the Exception base class.
I've considered using the decorator pattern, using an "ExceptionDecorator" class implementing an IException interface, however, doing this I would lose the initial exception type, which I do not want. For example for:
IException mException = new ExceptionDecorator( new NullPointerException() );
I would get:
mException instanceof ExceptionDecorator; //true
mException instanceof NullPointerException; //false
I want my custom exception to be an instance of NullPointerException.
This is totally generic, I want this to be working with any subclass of Exception.
Is this even possible ? If yes, maybe there's a pattern which could help me and I don't know about ?
I've done my best to be clear, if I'm not, please ask for more details and I will rephrase the initial topic.
Thanks
I want my custom exception to be an instance of NullPointerException.
It is not possible at compile time. To do what you want, you should create dynamically your exception class at runtime with Javasist for example.
Otherwise for static typing, you could use decorators. Decorators have to use the same interface/class than decorated objects. It is the base of the decorator.
In your case, the base class cannot be a new interface you create since you cannot change the code of existing exceptions. So the common abstract class between decorator and decorated objects is Exception.
You could have a decorator like that :
public class DecoratorException extends Exception{
private Exception decorated;
private boolean isStupid;
public DecoratorException(Exception exception){
this.decorated = exception;
}
public void setStupid(boolean iValue){
// TODO
}
public boolean getStupid{}{
// TODO
}
// get effective exception
public Exception getEffectiveException(){
return decorated;
}
// decorate the method you wish
// for example toString()
public String toString(){
return decorated.toString() + ", isStupid=" + isStupid);
}
}
The idea of Decorator is adding behavior to the decorated object.
In my example, I decorated the toString() method to display the new field with its value.
You can then rise an exception like that :
Exception e = new DecoratorException(new IllegalArgumentException());
e.setStupid(true);
throw e;
Thanks you all for your answers, it seems like nothing can really satisfy what I need. So I may just change my idea rather than forcing something that would turn awkward and not maintainable
I think your best bet here would be to continue with the decorator pattern here as you described, and instead of using instance of, create another method in your exception class (#containsInstanceOf or something) and using that in your code to check the contained type.
I think the only way to add the behavior you want would be to mess with the byte code like Lombok does, or by creating proxy objects. Both of those are pretty messy and it's probably easier to just use the decorator pattern and deal with the fact that instance of won't work.
For getting the exception class to extend NullPointer, do something like this:
public MyNewException extends NullPointerException
{
/*define methods and variables*/
}
For a class to work with any subclass of exception, you would have to define it as follows:
public MyNewException extends Exception
{
/*define stuff*/
}
Let me know if this is not what you want to be done.

How to retrieve implementing class/interface of parent interface?

I am clear with polymorphism and inheritance concept of oop, but I am in a situation where I need to know the implementing class. For example:
public CommonReadRepository<?> getReadRepository(String tableName) {
if (tableName == null)
return null;
switch (tableName) {
case "order":
return orderRepository;
...
}
return null;
}
The interface orderRepository extends CommonReadRepository, and because of my requirement, I need to access a function defined in orderRepository.
CommonReadRepository<?> repository=getReadRepository("order");
Is there any way to check back the implementing (child) class or interface of CommonReadRepository?
Of course, I can always do something like this:
if(tableName=="order")
return (OrderRepository)CommonReadRepository<?>;
I tried to debug getReadRepository("order"), but it gives me an instance of JdkDynamicAopProxy, and I am not sure how it works.
if(interface is instanceof xyz class)
i do not want to use it because i have 100 of classes and i want to keep it as a last resort... or in other words
i don't know about xyz class
Thanks
Following is one way to check if the returned Object is an instance of the specified class:
CommonReadRepository<?> repository=getReadRepository("order");
if(repository instanceof WhatEverSubclass) {
// do something
}
But using this approach is not how OOP is supposed to be done. If your classes all implement the same Interface, why don't you define a common method, that's then used in all the subclasses, but implement it differently every time.
I think, what you try to do is not getting you anywhere.
You can find all available classes inheriting an interface using the reflections tool (https://github.com/ronmamo/reflections). I used it for a dependency injector and it works very reliable.
Yet, why don't you just use the instanceof operator to make sure the object is of the right type:
if( repository instanceof OrderRepository) return (OrderRepository)repository;
But still, this won't change the return type of your function and you need to inspect the type of the returned value again outside of your function.
Update: If this happens for hundreds of objects, you could change the getRepository method to return a type you give as parameter: <T> getRepository(String name, Class<T> expectedType)
This will allow you OrderRepository o = getRepository("order", OrderRepository.class);

ClassLoad an Enum type

How would one go about instantiating an Enum type via a ClassLoader or similar mechanism? (I'm trying to keep everything under the same context classloader for a standalone server application).
I have something like:
ClassLoader loader = new CustomClassLoader(parent, libDir);
Thread.currentThread().setContextClassLoader(loader);
// trouble area
Class<?> containerClass = loader.loadClass("com.somepackage.app.Name$SERVER");
I had wrongly thought simply loading the Enum would be enough to kick it off (it's private constructor contains startup method calls and what-not).
Doing what I have above does not result in any exceptions, but the JVM just terminates after the last line and the server does not start up.
Obviously doing:
containerClass.newInstance();
Results in an exception being thrown.
To expand on my comment, I think the cleanest you'll get is something like this:
public static <T extends Enum<T>> T loadEnum(ClassLoader loader, String classBinaryName, String instanceName) throws ClassNotFoundException {
#SuppressWarnings("unchecked")
Class<T> eClass = (Class<T>)loader.loadClass(classBinaryName);
return Enum.valueOf(eClass, instanceName);
}
There is really no way to avoid the unchecked cast from Class<?> to a proper enum type. But at least the #SuppressWarnings is limited in scope.
Edit:
Upon further checking, there is actually a simpler way of achieving what you need, without needing to know the name of an instance and without warnings:
Class<?> containerClass = loader.loadClass("com.somepackage.app.Name");
containerClass.getEnumConstants()
Loading an enum doesn't cause it to initialize. You have to reference it through either a field reference or a method reference. So even a simple statement like Name name = Name.SERVER; or Name.SERVER.name(); would do the trick.
See section 5.5 Initialization in chapter 5. Loading, Linking, and Initializing of the Java Virtual Machine Specification.

Obtaining the original Java class while using instanceof and casting

First off, for anyone out there who abhors, detests and despises the instanceof operator, I understand your concerns with it, but am stuck using it. That's because I don't have the authority to completely refactor the way another development team set a project up, so unless I'm missing somethin here, I just don't see any way of avoiding it.
I have a Java POJO that cannot be changed, and allows you to set an Exception as one of its properties:
public class Message {
private Exception exception;
public void setException(Exception exc) {
this.exception = exc;
}
}
Again, I can't change this Message class.
I am writing an error handler method that gets passed a MessageContainer instances, and I need logic to do different things depending on what type of exception was set on the container's Message:
public class ErrorHandler {
public void handle(MessageContainer container) {
Message msg = container.getMessage();
Exception exc = msg.getException();
if(exc instanceof FizzException)
System.out.println("Do x");
else if(exc instanceof BuzzException)
System.out.println("Do y");
else
System.out.println("Do z");
}
}
Again, I can't change the fact that ErrorHandler#handle is passed a MessageContainer and not an injectable Message instance.
So, even though I really don't like to use instanceof, I don't see any other way of accomplishing this logic (but by all means, please make suggestions...as long as they don't involve making changes to Message, MessageContainer, or the handle(MessageContainer) method!).
But even with using instanceof, how does this code even work? Once you pull the Exception out of the Message, I don't think any of the instanceofs will fire, because its cast to an Exception, with no way to detect if it's BuzzException, FizzException, etc. What are my options here? Thanks in advance.
This code will work as expected. During runtime, instanceof statements will compare the actual type of exc, and not just assume this is only an Exception. If the only statement that worked was exc instanceof Exception, instanceof would be totally worthless :)
Another solution (which I would avoid to use) would be to compare fully qualified class names:
String fqcn = exc.getClass().getName();
if (fqcn.equals("com.foo.FizzException") {
// etc.
}
The cast to exception on
Exception exc = msg.getException();
does not erase the exception runtime type. It has merely cast it to a base type. The instanceof will still work. However, if your FizzException extends BuzzException, then you will need to do the instanceof checks in the other order. i.e. check for the most derived type first.
Otherwise, it will go into the base class check clause instead of the derived one.
It's not clear what you want. If the exceptions are all "given" and you can't change their implementations then you can use exception.getClass().getName() to get the class name and, maybe, look it up in a table or whatever to pick your course of action.
If you can change many of the exception implementations have them all implement an interface that provides a "functionality()" method or whatever. If an given Exception object is instanceof MyFunctionalityInterface then cast to MyFunctionalityInterface and call functionality() to have it return the info you need to guide your actions. Then use instanceof or getClass().getName() to manage the Exception classes you can't change.

Refactoring Java factory method

There's something very unsatisfactory about this code:
/*
Given a command string in which the first 8 characters are the command name
padded on the right with whitespace, construct the appropriate kind of
Command object.
*/
public class CommandFactory {
public Command getCommand(String cmd) {
cmdName = cmd.subString(0,8).trim();
if(cmdName.equals("START")) {
return new StartCommand(cmd);
}
if(cmdName.equals("END")) {
return new EndCommand(cmd);
}
// ... more commands in more if blocks here
// else it's a bad command.
return new InvalidCommand(cmd);
}
}
I'm unrepentant about the multiple exit points - the structure is clear. But I'm not happy about the series of near-identical if statements. I've considered making a Map of Strings to Commands:
commandMap = new HashMap();
commandMap.put("START",StartCommand.class);
// ... etc.
... then using Reflection to make instances of the appropriate class looked up from the Map. However while conceptually elegant, this involves a fair amount of Reflection code that whoever inherits this code might not appreciate - although that cost might be offset by the benefits. All the lines hardcoding values into the commandMap smell almost as bad as the if block.
Even better would be if the factory's constructor could scan the classpath for subclasses of Command, query them for String representations, and automatically add them them to its repertoire.
So - how should I go about refactoring this?
I guess some of the frameworks out there give me this kind of thing for free. Let's assume I'm not in a position to migrate this stuff into such a framework.
How about the following code:
public enum CommandFactory {
START {
#Override
Command create(String cmd) {
return new StartCommand(cmd);
}
},
END {
#Override
Command create(String cmd) {
return new EndCommand(cmd);
}
};
abstract Command create(String cmd);
public static Command getCommand(String cmd) {
String cmdName = cmd.substring(0, 8).trim();
CommandFactory factory;
try {
factory = valueOf(cmdName);
}
catch (IllegalArgumentException e) {
return new InvalidCommand(cmd);
}
return factory.create(cmd);
}
}
The valueOf(String) of the enum is used to find the correct factory method. If the factory doesn't exist it will throw an IllegalArgumentException. We can use this as a signal to create the InvalidCommand object.
An extra benefit is that if you can make the method create(String cmd) public if you would also make this way of constructing a Command object compile time checked available to the rest of your code. You could then use CommandFactory.START.create(String cmd) to create a Command object.
The last benefit is that you can easily create a list of all available command in your Javadoc documentation.
Your map of strings to commands I think is good. You could even factor out the string command name to the constructor (i.e. shouldn't StartCommand know that its command is "START"?) If you could do this, instantiation of your command objects is much simpler:
Class c = commandMap.get(cmdName);
if (c != null)
return c.newInstance();
else
throw new IllegalArgumentException(cmdName + " is not as valid command");
Another option is to create an enum of all your commands with links to the classes (assume all your command objects implement CommandInterface):
public enum Command
{
START(StartCommand.class),
END(EndCommand.class);
private Class<? extends CommandInterface> mappedClass;
private Command(Class<? extends CommandInterface> c) { mappedClass = c; }
public CommandInterface getInstance()
{
return mappedClass.newInstance();
}
}
since the toString of an enum is its name, you can use EnumSet to locate the right object and get the class from within.
With the exception of the
cmd.subString(0,8).trim();
part, this doesn't look too bad to me. You could go with the Map and use reflection, but, depending on how often you add/change commands, this might not buy you much.
You should probably document why you only want the first 8 characters, or maybe change the protocol so it's easier to figure out which part of that string is the command (e.g. put a marker like ':' or ';' after the command key-word).
Its not directly an answer to your question, but why don't you throw an InvalidCommandException (or something similar), rather then returning an object of type InvalidCommand?
Unless there is a reason they can't be I always try to make my command implementations stateless. If that's the case you can add a method boolean identifier(String id) method to your command interface which would tell whether this instance could be used for the given string identifier. Then your factory could look something like this (note: I did not compile or test this):
public class CommandFactory {
private static List<Command> commands = new ArrayList<Command>();
public static void registerCommand(Command cmd) {
commands.add(cmd);
}
public Command getCommand(String cmd) {
for(Command instance : commands) {
if(instance.identifier(cmd)) {
return cmd;
}
}
throw new CommandNotRegisteredException(cmd);
}
}
I like your idea, but if you want to avoid reflection you could add instead instances to the HashMap:
commandMap = new HashMap();
commandMap.put("START",new StartCommand());
Whenever you need a command, you just clone it:
command = ((Command) commandMap.get(cmdName)).clone();
And afterwards, you set the command string:
command.setCommandString(cmdName);
But using clone() doesn't sound as elegant as using reflection :(
Taking a Convetion vs Configuration approach and using reflection to scan for available Command objects and loading them into your map would be the way to go. You then have the ability to expose new Commands without a recompile of the factory.
Another approach to dynamically finding the class to load, would be to omit the explicit map, and just try to build the class name from the command string. A title case and concatenate algorithm could turn "START" -> "com.mypackage.commands.StartCommand", and just use reflection to try to instantiate it. Fail somehow (InvalidCommand instance or an Exception of your own) if you can't find the class.
Then you add commands just by adding one object and start using it.
One option would be for each command type to have its own factory. This gives you two advantages:
1) Your generic factory wouldn't call new. So each command type could in future return an object of a different class according to the arguments following the space padding in the string.
2) In your HashMap scheme, you could avoid reflection by, for each command class, mapping to an object implementing a SpecialisedCommandFactory interface, instead of mapping to the class itself. This object in practice would probably be a singleton, but need not be specified as such. Your generic getCommand then calls the specialised getCommand.
That said, factory proliferation can get out of hand, and the code you have is the simplest thing that does the job. Personally I'd probably leave it as it is: you can compare command lists in source and spec without non-local considerations like what might have previously called CommandFactory.registerCommand, or what classes have been discovered through reflection. It's not confusing. It's very unlikely to be slow for less than a thousand commands. The only problem is that you can't add new command types without modifying the factory. But the modification you'd make is simple and repetitive, and if you forget to make it you get an obvious error for command lines containing the new type, so it's not onerous.
Having this repetitive object creation code all hidden in the factory is not so bad. If it has to be done somewhere, at least it's all here, so I'd not worry about it too much.
If you really want to do something about it, maybe go for the Map, but configure it from a properties file, and build the map from that props file.
Without going the classpath discovery route (about which I don't know), you'll always be modifying 2 places: writing a class, and then adding a mapping somewhere (factory, map init, or properties file).
Thinking about this, You could create little instantiation classes, like:
class CreateStartCommands implements CommandCreator {
public bool is_fitting_commandstring(String identifier) {
return identifier == "START"
}
public Startcommand create_instance(cmd) {
return StartCommand(cmd);
}
}
Of course, this adds a whole bunch if tiny classes that can't do much more than say "yes, thats start, give me that" or "nope, don't like that", however, you can now rework the factory to contain a list of those CommandCreators and just ask each of it: "you like this command?" and return the result of create_instance of the first accepting CommandCreator. Of course it now looks kind of akward to extract the first 8 characters outside of the CommandCreator, so I would rework that so you pass the entire command string into the CommandCreator.
I think I applied some "Replace switch with polymorphism"-Refactoring here, in case anyone wonders about that.
I'd go for the map and creation via reflection. If scanning the class path is too slow, you can always add a custom annotation to the class, have an annotation processor running at compile time and store all class names in the jar metadata.
Then, the only mistake you can do is forgetting the annotation.
I did something like this a while ago, using maven and APT.
The way I do it is to not have a generic Factory method.
I like to use Domain Objects as my command objects. Since I use Spring MVC this is a great approach since the DataBinder.setAllowedFields method allows me a great deal of flexibility to use a single domain object for several different forms.
To get a command object, I have a static factory method on the Domain object class. For example, in the member class I'd have methods like -
public static Member getCommandObjectForRegistration();
public static Member getCommandObjectForChangePassword();
And so on.
I'm not sure that this is a great approach, I never saw it suggested anywhere and kind of just came up with it on my own b/c I like the idea of keeping things like this in one place. If anybody sees any reason to object please let me know in the comments...
I would suggest avoiding reflection if at all possible. It is somewhat evil.
You can make your code more concise by using the ternary operator:
return
cmdName.equals("START") ? new StartCommand (cmd) :
cmdName.equals("END" ) ? new EndCommand (cmd) :
new InvalidCommand(cmd);
You could introduce an enum. Making each enum constant a factory is verbose and also has some runtime memory cost. But you can eaily lookup an enum and then use that with == or switch.
import xx.example.Command.*;
Command command = Command.valueOf(commandStr);
return
command == START ? new StartCommand (commandLine) :
command == END ? new EndCommand (commandLine) :
new InvalidCommand(commandLine);
Go with your gut, and reflect. However, in this solution, your Command interface is now assumed to have the setCommandString(String s) method accessible, so that newInstance is easily useable. Also, commandMap is any map with String keys (cmd) to Command class instances that they correspond to.
public class CommandFactory {
public Command getCommand(String cmd) {
if(cmd == null) {
return new InvalidCommand(cmd);
}
Class commandClass = (Class) commandMap.get(cmd);
if(commandClass == null) {
return new InvalidCommand(cmd);
}
try {
Command newCommand = (Command) commandClass.newInstance();
newCommand.setCommandString(cmd);
return newCommand;
}
catch(Exception e) {
return new InvalidCommand(cmd);
}
}
Hmm, browsing, and only just came across this. Can I still comment?
IMHO there's nothing wrong with the original if/else block code. This is simple, and simplicity must always be our first call in design (http://c2.com/cgi/wiki?DoTheSimplestThingThatCouldPossiblyWork)
This seems esp true as all the solutions offered are much less self documenting than the original code...I mean shouldn't we write our code for reading rather than translation...
At the very least, your command should have a getCommandString() -- where StartCommand overrides to return "START". Then you can just register or discover the classes.
+1 on the reflection suggestion, it will give you a more sane structure in your class.
Actually you could do the following (if you haven't thought about it already)
create methods corresponding to the String you'd be expecting as an argument to your getCommand() factory method, then all you have to do is reflect and invoke() these methods and return the correct object.

Categories