Does the following code violate the EJB 3 specifiation? If so, what can I do about it to retain the desired functionality?
The reason why I'm asking is that IntelliJ 14 produces these warnings:
The class(es) I want to instantiate is no EJB, just a POJO, and the EJB serves as a repository for these POJO's (they are encapsulating business logic).
@Stateless
public class MyBean {
public SomeInterface createSomeClass(final Class<? extends AbstractSomeClass> someClass, final MyArgument argument) {
try {
final Constructor constructor = someClass.getDeclaredConstructor(argument.getClass());
constructor.setAccessible(true);
return (SomeInterface) constructor.newInstance(state);
} catch (InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException e) {
// TODO fix exception handling
throw new RuntimeException(e);
}
}
}
Thank you for your help.
Regards,
Simon
Edit
It seems to me that there is a section in the EJB 3 specification that answers the first part of my question:
The enterprise bean must not attempt to query a class to obtain information about the declared members that are not otherwise accessible to the enterprise bean because of the security rules of the Java language. The enterprise bean must not attempt to use the Reflection API to access information that the security rules of the Java programming language make unavailable.
I've never heard of this before and don't understand the reason behind this rule. Stateful EJB's might be an alternative for my problem but that is too heavy-weight for my taste.
This paragraph is really just a heavy-handed restatement of the minimum Java 2 Security Policy for the EJBs (section 16.3 of the EJB 3.2 spec). The spec does not guarantee that your EJB will have permission to do what it does. If you don't have Java 2 security enabled in your application server or you have granted your EJB permission to do that, then you should be fine. (Of course, the normal caveats for inspecting/changing the state of objects you don't own still apply.)
If you want to avoid the warning anyway, then an alternative might be to create a factory interface:
interface AbstractSomeClassFactory<T> { T create(MyArgument a); }
...and pass that to the EJB instead. I don't have any other great ideas.