Is there a way to inject final class with guice? - java

I have provider which should inject javax.mail.Session (provider looks it up in env. context of tomcat) as singleton. There is a problem when I use field injection somewhere in code:
java.lang.IllegalArgumentException: Cannot subclass final class class javax.mail.Session
Is there a way to go round this? Only clues that I've found point to Spring AOP/Proxies.
Thanks && regards

Look at this http://code.google.com/p/google-guice/wiki/AOP. It seems that there is some limitations:
Limitations
Behind the scenes, method interception is implemented by generating
bytecode at runtime. Guice dynamically creates a subclass that applies
interceptors by overriding methods. If you are on a platform that
doesn't support bytecode generation (such as Android), you should use
Guice without AOP support.
This approach imposes limits on what classes and methods can be
intercepted:
Classes must be public or package-private. Classes must be non-final
Methods must be public, package-private or protected Methods must be
non-final Instances must be created by Guice by an #Inject-annotated
or no-argument constructor

Related

DI with arguments in the constructor

So I'm implementing a Dependency Injection framework into my Java project (Google Guice) and everything is pretty good, I like it but there's a small problem;
I want to make a static instance of my main project's class (where it instantiates the dependencies, etc). But I don't know any method to instantiate it using Guice, I can't instantiate it manually because I'm using DI in the constructor of it (I have objects in the constructor) which means that I am not able to access the class' non-static variables needed to instantiate the class.
I tried using a Provider but I couldn't really understand where to bind it, because I don't want to have an interface for the main class (will if needed).
If you are wanting to mix a static instance of a class with dependency injection, you have somewhat missed the point of dependency injection: you can simply inject the instance of the class.
If you want there to be a single instance of a class for your injector, bind it in #Singleton scope: either:
bind(YourClass.class).in(Singleton.class);
in your module's configure() method, or
#Provides #Singleton YourClass provideYourClassInstance() {
// ...
}
in your module, or
#Singleton class YourClass {
// ...
}
in the actual class declaration.
Then just inject this instance like any other:
class SomeOtherClass {
#Inject SomeOtherClass(YourClass instance) {
// ... Do something with instance, like assign it to a field.
}
}
The point is that SomeOtherClass shouldn't need know anything about the lifetime of instance: it simply doesn't matter whether this is a singleton instance, or every class using it has its own instance.
You can get three different answers here depending on the question.
To directly answer the question in the title (DI with arguments in the constructor), you can mix DI with constuctor arguments by instead injecting a Factory. Though you're welcome to write one manually, Guice can do this for you as assisted injection (see FactoryModuleBuilder), or you can use the equivalent code-generated solution AutoFactory popular through Dagger.
If you're trying to initialize a static class's fields in a Guice application, Guice can do that for you as soon as the Injector is created. Simply call requestStaticInjection in a Module you feed to Guice. This, as Andy Turner pointed out, will cause you to miss out on some of the benefits of Guice: Because you're injecting the instance statically, there's very little opportunity for you to provide replacement implementations in tests or in other class reuse. Guice describes this more in the static injections section of its wiki:
When migrating an application from static factories to Guice, it is possible to change incrementally. Static injection is a helpful crutch here. It makes it possible for objects to partially participate in dependency injection, by gaining access to injected types without being injected themselves. [...]
Static members will not be injected at instance-injection time. This API is not recommended for general use because it suffers many of the same problems as static factories: it's clumsy to test, it makes dependencies opaque, and it relies on global state.
The best overall solution is in Andy's answer: Adapt your application to use DI, which will let it inject the objects that you would otherwise make static.

Why CDI beans don't support final methods

I just incurred in the infamous JavaEE CDI error under GlassFish server:
org.glassfish.deployment.common.DeploymentException: CDI deployment failure:Exception List with 2 exceptions:
Exception 0 :
org.jboss.weld.exceptions.DeploymentException: WELD-001437 Normal scoped bean class ASController is not proxyable because the type is final or it contains a final method public final void ASController.selectPath(org.primefaces.event.NodeSelectEvent) - Managed Bean [class ASController] with qualifiers [#Default #Any #Named].
the error is quite explicative in the fact that he doesn't like final methods inside a CDI bean, however I can't grasp why.
At this link
http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html_single/#d0e1429
they explain it is something to do with serialization but I can't see why serializing a class with a final method should be any harder than one with non final methods.
Well, there is several ways in which you can implement a proxy object. But since you expect the proxy to have the "same" type as the proxied bean, you'll have to use inheritance (or demand interfaces which you then could implement, but this would not be an approach where every POJO could be a bean for CDI).
That is, they internally extend from the class you want to inject, generate some proxy code around that and give you that sub class.
This proxy then is handling all the magic to make sure you always have a bean fitting your context (and this bean has all the members variable beans pointing to the just right beans).
So you are not really receiving the type of the bean you want to inject, but a proxy subclass of that bean. This does not work very well with final methods and classes and private constructors.
If the class is not final, the proxy can extend this class, it however cannot easily overwrite the final method of yours. This however may be needed (if e.g your bean is serialized, the proxy needs to deserialize it).
There is, more complicated ways, around that. One could inject this functionality by manipulating the byte code of your class via an agent (e.g removing the final modifiers, inject a default constructor, ...) and maybe even mix this with inheritance, but this is just not implemented, yet (and also non trivial to support over several JVM implementations).
From the linked resource a note indicating that this is planned for a future release:
Note
A future release of Weld will likely support a non-standard workaround
for this limitation, using non-portable JVM APIs:
Sun, IcedTea, Mac: Unsafe.allocateInstance() (The most efficient)
IBM, JRockit: ReflectionFactory.newConstructorForSerialization()
But we didn't get around to implementing this yet.
Container create proxy object for injected classes. So, container doesn't use your classes, but those classes extends. Java prohibit extends final classes, so you cannot use final classes in CDI.

Guice 3.0 - Purpose of Constructor Bindings?

I've just read the chapter about Constructor Bindings in Guice's User Guide but don't really understand when to use Constructor bindings.
As far as I understand, they provide the same functionality as #Provider methods, except instances created with Constructor Bindings participate in AOP. Is this correct? Can anyone give a better example than the one in the doc?
As far as I understand, they provide the same functionality as #Provider methods, except instances created with Constructor Bindings participate in AOP.
That's more or less correct, though there are some advantages that constructor binding has. Basically, it's a way of binding to a class as if it had an #Inject on a specific constructor even if it doesn't and you can't add the annotation yourself. Unlike #Provides methods, you could write utilities to allow you to do more interesting things. For instance, you could have a utilitiy method that returns the only constructor of a class, throwing an exception if there are more than one:
bind(Foo.class).toConstructor(getOnlyConstructor(FooImpl.class));
You could also use some other annotation (besides #Inject) if you wanted for some reason and have a utility method that gets the constructor that's annotated with that for binding.

Java EJB interfaces

Could anyone explain me how do the functions inside the HOME and REMOTE interfaces relate to the Bean object?
The interfaces are instanciated so that the functions are used. But the functions body rests only in the Bean object. What am I missing?
The actual EJB instances will typically be instances of java.lang.reflect.Proxy that delegate calls to the bean's implementation class after doing their transaction-, clustering- and security-stuff.
The Java EE container is dealing with those details for you. It knows to find the bean implementation when a call is made to that interface. It hides all the magic from you.

Why does dependecy injection use public methods?

Why does dependecy injection use public methods?
Correct me if I'm wrong, but it's possible to change the implementation using reflexion.
DI is not a goal in itself. The purpose of DI is to enable loose coupling through favoring composition over inheritance, and that's only possible if you expose a public API for the purpose.
You can't recompose components in new and exiting ways without the public API.
That's a pretty blanket statement and isn't true. My preference is generally to use package-private constructors (or public constructors on package-private classes, since it doesn't matter then) for dependency injection since that allows you to instantiate and inject a class yourself (with no reflection or injector) for testing in a test class in the same package.
Keep in mind that the security policy may prevent one from calling protected, package private, or private methods even via the reflection API. If the DI framework is to work in all environments, then it can only rely on public methods.
Just to elaborate on the answer ColinD gave (I never even knew about package-private classes until a year of programming Java). With an app developed with a DI framework I believe you would make interfaces public and perhaps some abstract classes and Enums:
package org.my.service;
public interface Service {
public void process();
}
Then, the concrete implementation would be package-private (no public keyword)
package org.my.service;
class RealService {
public void process() {/*do something*/}
}
This enforces the concept of information hiding and means implementation details do not leak into the public API. It also means you cannot use the class outside of that package (compile-time error if you try -- you can't "new" it anywhere).
Again as ColinD said, you can unit test it because your unit test will reside in org.my.service.
DI frameworks have many ways to inject dependencies
constructor injection
setter injection
initializer injection
field injection
By using the first three, with modifier public you can set the dependencies manually even if the class is used outside a DI framework.
However, the 4th option is widely used. The most common scenario where you may need to manually set the dependencies are unit tests. For that spring, for example, offers ReflectionTestUtils, so that you can inject into fields with 1 line, and that is more or less fine.

Categories