Injection order of "MembersInjector" and a regular "Method"-Injection wrong? - java

I am using google-guice since a couple of days, and I am getting more and more impressed.
I created a MemberInjector to easily integrate the logging framework SLF4J, just with a additional annotation. That means instead of using always the long term:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
I am now just using:
#Log
Logger LOG;
This is really great, BUT:
I am also using a method-injection as a kind of starter function like this in the same class, AND if I access to the LOG instance there, it causes a NPE! Because it is not injected yet.
#Inject
public void start() {
//And here is the problem...
LOG.info("in start") //causes NPE, cause LOG is not injected yet
}
If I use the LOG instance in another (non-injected) method it works perfectly,.
Is there a way to change the injection order or is it possible to tell guice to inject the MemberInjector earlier? Cause I really would like to use the logging also in the method-injection part.
Thank for any hint.

One solution I found was to create just a additional listener that looks for a defined method like ("init" or "start") and just calls it after creation and injection of members.
See in module configuration:
#Override
protected void configure() {
bindListener(Matchers.any(), new InitMethodTypeListener());
//...
InitMethodTypeListener:
public class InitMethodTypeListener implements TypeListener {
private static final Logger log = LoggerFactory.getLogger(InitMethodTypeListener.class);
#SuppressWarnings("rawtypes")
static class InitInvoker implements InjectionListener {
#Override
public void afterInjection(final Object injectee) {
try {
log.info("Invoke init() from Class: {}", injectee.getClass().getName());
injectee.getClass().getMethod("init").invoke(injectee);
} catch (final Exception e) {
log.error(e.getMessage(), e);
}
}
public static final InitInvoker INSTANCE = new InitInvoker();
}
#SuppressWarnings("unchecked")
#Override
public <I> void hear(final TypeLiteral<I> type, final TypeEncounter<I> encounter) {
try {
if (type.getRawType().getMethod("init") != null) {
encounter.register(InitInvoker.INSTANCE);
}
} catch (final NoSuchMethodException | SecurityException e) {
// do nothing here, if not init-method found - no call
}
}
}
Maybe it not the straight forward way but it works. And so I am sure all members are injected well when the init-method is called.
With this implementation all objects that are under guice control their "init"-method will be called automatically after object creation and injection.

Related

Java Tyrus WebSocket Client #OnMessage method gets called on 'different' object

I have created a WebSocket client using Tyrus.
The problem happens in the #OnMessage annotated instance method.
Within the enclosing class I have three things that seem to both have conflicting instance contexts.
I have a Logger instance in the parent class. The getter getLogger() returns the valid logger instance.
A LinkedList object for enqueuing messages. This throws a NullPointerException and is the core problem.
The enclosing instance object.
private LinkedList<String> messageQueue = new LinkedList<>();
private Logger logger = LoggerFactory.fromClass(WebSocketClient.class);
public Logger getLogger() {
return logger;
}
public WebSocketClient() {
super();
this.getLogger().info(this.toString());
}
public start() {
try {
WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();
this.connectionSession = webSocketContainer.connectToServer(WebSocketClient.class, URI.create("WebSocket URL here"));
} catch (Exception exception) {
this.getLogger().error("Exchange Client Start Error", exception);
}
}
#OnMessage
public void processMessage(String message) {
// This returns the correct Logger instance
this.getLogger().info("Received Message: " + message);
// This Returns a different hashCode()
this.getLogger().info(this.toString());
// This throws a NullPointerException
this.messageQueue.add(message);
}
Through my debugging in the constructor when I log this.getLogger().info(this.toString()); and that returns the proper package, class name with the #hashCode().
But when I log it in the processMessage() method and returns a completely different hashCode().
Based on my research, hashCode on Object based classes should return the exact same hashCode.
Which leads me to believe that the processMessage is being called on either a duplicate (copy) object or something like that.
Any help would be great.
Instead of using WebSocketContainer to connectToServer I used
ClientManager client = ClientManager.createClient();
client.connectToServer(this, URI.create("WebSocket URL here"));
It seems WebSocketContainer follows the convention of finding a service provider and that might have been the issue as the service provider could've had a different implementation (Talking out of my ass here).

How would I test logging in my application? New to Mockito and testing- seeking direction

I'm attempting to figure out how to test a method written in my LoggingRestService class. I'd like to verify that my (external) error method produces the correct log entry in this logger.
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingRestService.class);
#POST
#Path("debug")
#ApiOperation(value = "Writes js error message log. (not secured)")
#ApiResponse(code = 200, message = "Message logged")
public void getUserList(#ApiParam(value = "Js debug message.")
String message) {
ConverterUtils.error(LOGGER, message, null);
}
}
Here is ConverterUtils error method:
public static void error(Logger logger, String mess, Exception ex) {
Class<?> aClass = logger.getClass();
try {
Method method = aClass.getMethod("error", String.class, Throwable.class);
method.invoke(logger, mess, ex);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
LOGGER.error("get logger error", e);
}
}
I've never used mockito but I am somewhat familiar with the concept of mocking classes..still I'm a little boggled. I was not given much direction for testing and attempting to be self sufficient is slowly rotting my confidence. Thanks a bunch.
Let me check if I get what you are saying: you want to verify that your ConverterUtil class is calling the error method with the appropriate message and exception right.
To be able to do that you would need to make sure that your ConverterUtils class is called with a mock version of a Logger. You can do that with mock(Logger.class). That will work even if Logger is a class and not an interface because Mockito can mock classes that are not final. It will actually create a subclass for you.
Your test code will look:
Logger mockedLogger = mock(Logger.class);
String expectedMessage = "Whatever";
Exception expectedException = new Exception();
// Business method
ConverterUtils.error(mockedLogger, expectedMessage, expectedException);
// Asserts
verify(mockedLogger).error(expectedMessage, expectedException);
On a side node: it puzzles me why the error method is not as simple as:
public static void error(Logger logger, String mess, Exception ex) {
logger.error(mess, ex);
}
I really don't see why you need to use the reflection layer here. You know exactly what method you want, so why don't you simply invoke the method as is.

Post Construct is not called

I wrote a managed bean with post construct method (using #PostContruct), but the method is not being called. I'm using liferay liferay-portal-6.1.2-ce-ga3 with Jboss 7.1.1, and Icefaces 3.0. Can someone help me figure this out?
#SessionScoped
#ManagedBean
public class DetalleVaPortletBean extends BackingPortletUI {
private static final long serialVersionUID = -7127465434575796794L;
public DetalleVaPortletBean() {
try {
System.out.println(this);
} catch (Exception e) {
error(e);
}
}
#PostConstruct
public void postConstruct(){
adicionarPortletPrincipal();
}
}
First of all, enshure that your DetalleVaPortletBean object really is constructed by examin the console output and locate the output from
System.out.println(this);
It might be helpul with some more printouts in the constructor, e.g. System.out.println("DetalleVaPortletBean CTOR");

applying google guice to method dependencies

Consider the following servlet code:
public class AddDevice extends JsonServlet {
private static final long serialVersionUID = 1L;
#Override
protected void doGet(final JsonServletRequest request,
final JsonServletResponse response) throws ServletException,
IOException {
try {
final DeviceEntity device = new DeviceEntity();
device.type =
FleetManagerDatabaseHelper
.deviceTypesAccessor()
.queryForId(Integer.valueOf(
request.getParameter(DeviceTypeEntity._ID)));
device.sn = request.getParameter(DeviceEntity._SN);
device.status = Long.valueOf(0);
FleetManagerDatabaseHelper.devicesAccessor().create(device);
}
catch (final SQLException e) {
throw new ServletException("device already exists");
}
}
}
This code depends on the DeviceEntity and on the FleetManagerDatabaseHelper classes.
Now, I would like to write a test for it checking that the created entity is filled with the correct type, sn and status values.
For this purpose I could create a FleetManagerDatabaseHelperMockup class.
How would you apply Google Guice (or something else) here with minimal changes?
Your first step is to design for dependency injection--avoid constructors and static methods, and instead take in instances that you require. It looks like those types are Provider<DeviceEntity>, DevicesAccessor, and DeviceTypesAccessor.
Provider is a very simple Guice interface that provides instances of whatever class is in its type argument via a single no-arg method get(). If you have bound Foo, Guice automatically knows how to bind Provider<Foo>. It is extremely useful if your instances are expensive, or if you need more than one over the lifetime of your servlet (as you do).
After refactoring for dependency injection, your class will look like this:
public class AddDevice extends JsonServlet {
private static final long serialVersionUID = 1L;
private final Provider<DeviceEntity> deviceEntityProvider;
private final DevicesAccessor devicesAccessor;
private final DeviceTypesAccessor deviceTypesAccessor;
#Inject
public AddDevice(Provider<DeviceEntity> deviceEntityProvider,
DevicesAccessor devicesAccessor,
DeviceTypesAccessor deviceTypesAccessor>) {
this.deviceEntityProvider = deviceEntityProvider;
this.devicesAccessor = devicesAccessor;
this.deviceTypesAccessor = deviceTypesAccessor;
}
#Override
protected void doGet(final JsonServletRequest request,
final JsonServletResponse response) throws ServletException,
IOException {
try {
final DeviceEntity device = deviceEntityProvider.get();
device.type = deviceTypesAccessor.queryForId(
Integer.valueOf(request.getParameter(DeviceTypeEntity._ID)));
device.sn = request.getParameter(DeviceEntity._SN)
device.status = Long.valueOf(0);
devicesAccessor.create(device);
} catch (final SQLException e) {
throw new ServletException("device already exists");
}
}
}
At this point, it's extremely easy to write a test by passing in a Provider that keeps track of the instance it returns, along with a mock DevicesAccessor and a mock DeviceTypesAccessor. (I recommend Mockito.) If you write your own Provider interface and remove the #Inject, you don't even need to use Guice; in your tests, you could continue to use that constructor, but you would want to satisfy Java EE with a constructor like:
public AddDevice() {
this(new NewDeviceEntityProvider(),
FleetManagerDatabaseHelper.deviceTypesAccessor(),
FleetManagerDatabaseHelper.devicesAccessor());
}
private class NewDeviceEntityProvider implements Provider<DeviceEntity> {
#Override public DeviceEntity get() {
return new DeviceEntity();
}
}
But if you do want to use Guice to remove that boilerplate, just write a Guice Module. Your module would need to bind DeviceTypesAccessor and DevicesAccessor to the instances that FleetManagerDatabaseHelper would return; Guice would see that DeviceEntity has a no-arg constructor and would be able to inject DeviceEntity and Provider<DeviceEntity> automatically. (Comment if you want me to expand on what the Module would look like.)
Hope this helps!

Is it possible to automatically clean up resources at the end of scope in Guice?

Let's say I have a Closeable object injected through Guice using request scope:
#Provides #RequestScoped
public MyCloseableResource providesMyCloseableResource(){
return new MyCloseableResourceImpl();
}
Is it possible to hook-up a clean-up method that would automatically call close() on my resource when the scope exists, without resorting to custom scope implementation?
Looking at the custom scope implementation guide on the Guice wiki, it shows that scopes should be created and cleaned up like this:
/**
* Runs {#code runnable} in batch scope.
*/
public void scopeRunnable(Runnable runnable) {
scope.enter();
try {
// explicitly seed some seed objects...
scope.seed(Key.get(SomeObject.class), someObject);
// create and access scoped objects
runnable.run();
} finally {
scope.exit();
}
}
I am wondering if there is way to hook-up some custom clean-up code in the finally of the built-in scopes (especially session and request scopes).
If it isn't possible, might there be issues that would discourage this kind of automatic clean-up?
I have found ways of achieving the same effect in servlet containers by implementing a Filter to create and clean-up a resource per request, which works great but I am curious if it is possibly with pure Guice.
I faced a similar problem myself and finally rolled a Disposable interface which offers nothing but a public void dispose() method. I find this especially valuable for classes that register listeners somewhere and need to unregister them at a defined time. What I already had was my AttributeHolderScope which I blogged about so I won't repeat that part here. The only thing that is missing now is the AbstractAttributeHolder which looks like this:
/**
* An anstract base class for implementing the {#link AttributeHolder}
* interface which has an implementation of the attribute related methods.
*
* #author Matthias Treydte <waldheinz at gmail.com>
*/
public abstract class AbstractAttributeHolder
implements AttributeHolder, Disposable {
private final Object lock = new Object();
private transient Map<Object, Object> attributes;
public AbstractAttributeHolder() {
this.attributes = new HashMap<Object, Object>();
}
public void replaceAttributes(Map<Object, Object> newAttr) {
synchronized (getAttributeLock()){
this.attributes = newAttr;
}
}
#Override
public Object getAttributeLock() {
return this.lock;
}
#Override
public final void putAttribute(Object key, Object value) {
synchronized (getAttributeLock()) {
attributes.put(key, value);
}
}
#Override
public final boolean hasAttribute(Object key) {
synchronized (getAttributeLock()) {
return attributes.containsKey(key);
}
}
#Override
public final Object getAttribute(Object key) {
synchronized (getAttributeLock()) {
return attributes.get(key);
}
}
#Override
public final Set<Object> getAttributes() {
synchronized (getAttributeLock()) {
return Collections.unmodifiableSet(
new HashSet<Object>(this.attributes.values()));
}
}
#Override
public void dispose() {
synchronized (this.getAttributeLock()) {
for (Object o : this.attributes.values()) {
if (o instanceof Disposable) {
final Disposable d = (Disposable) o;
d.dispose();
}
}
this.attributes.clear();
}
}
}
This class itself implements Disposable so you can have nested scopes and when you dispose an outer scope, all nested scopes and, more importantly, all injected instances that implement Disposable get cleaned up. And to precisely answer you question: I don't think that this is possible with the Scope implementations provided by Guice itself, but it can be done. Everytime I look at this code I ask myself if this can't be done in a more concise way, but then it works beautifully (at least for me).

Categories