Using Struts 2’s native dependency injection support

Since I knew that Struts 2 used Guice internally, I was curious if the native DI support in S2 could be used in a simple application. A little bit of digging and fiddling around showed what is possible.

struts.xml

...
 <constant name="myVal" value="9" />
 <bean name="myService" type="prac.MyService" class="prac.MyServiceImpl" />
...

MyServiceImpl.java

...
 @Inject("myVal")
 public void setMyVal(String myVal) {
 this.myVal = Integer.parseInt(myVal);
 }
...

MyAction.java

...
 @Inject("myService")
 public void setMyService(MyService myService) {
 this.myService = myService;
 }
...

This will create a single instance of MyService with myVal injected into it.
And on every invocation of MyAction, that MyService instance will be injected into it.
Sweet!

Of course, this is part of Struts internals, so these can change at any time. It is probably not a good idea to use it on a real world system.

Object equality in Java

The first time I paid attention to the equals() method was when preparing for SCJP exam, where you have to know what the output of some lines of code will be. That was simple enough – follow the logic of the code, and make sure that you are not accidentally overloading equals instead of overriding it.

A few years later, I revisited equals() ( and hashcode() ) when reading Joshua Bloch’s Effective Java. Chapter 3, “Methods Common to All Objects” shows how to, and why you should, properly implement equals() method. This must be required reading for every Java programmer, even if you ever only write CRUD applications in Struts, and are never going to use any of it.

Recently, I read Angelika Langer‘s article on this subject. If, like me, you have read the Effective Java book, and think that you know all that you need to about Object equality, think again!

Angelika Langer and Klaus Kreft disect various approaches to implementing equals() – Secrets of equals().

The gist of it is that although implementing equals() for a final class, or a class with a final equals() method is reasonably straightforward, there is no one correct way of doing that with mixed-type comparisons allowed between objects of different types in the same class hierarchy.
The second thing to keep in mind is that if you are overriding a class that implements equals(), and you override the equals() method you have to pay particular attention to whether the superclass’s equals() method allows mixed-type comparisons or not –

If the designer of such a non-final class decides in favor of implementing equals() using instanceof , then no subclass can ever add fields and override equals() without violating the transitivity requirement of the equals() contract.
If the designer decides in favor of implementing equals() using getClass() , then no subclass object will ever be comparable to a superclass object and trivial extensions may not make a lot of sense.

There is a follow up article showing one way of Implementing equals() To Allow Mixed-Type Comparison.

Intellij IDEA – Add unambiguous imports as you type

One of my favourite settings in IDEA is to turn on the ‘Add unambiguous imports on the fly’ option.
With this on, if you type a class name, and that class is unique in the project libraries, IDEA automatically adds an import for that class. No need to stop typing to press ALT – ENTER.

So, I updated to IDEA 7 and found this wasn’t working anymore. Even more annoying, I couldn’t find this option in the settings. Turns out this setting has a new home.
In IDEA 7, it is has been moved to Settings|Code style|Imports.

Ref – EAP 7087 Release Notes

The link is out there – no more!

Remember the ‘Where would you like to go today’ slogan MS homepage used to have?

That’s what Erik’s Linkblog was like for me.
A few moments to spare and I used to head over to Erik’s Linkblog to see what good stuff I could find to read.

But no more! After many years of bringing us the best of the links (especially Java) every day, Eric is putting it to rest.

We will miss it Erik. Thanks for all the hard work.

Stringtree – Simple JSON in Java

If you are like me, you probabely find that most of the Java implementations of JSON are rather bloated, especially for simple uses of JSON. Most of the time, I only need to convert a simple map to JSON, which I do using a simple class I had written

Some time ago, I came accross a very simple implementation of JSON-Java converstion. See Stringtree JSON .

It is a nice, simple implementation consisting of all of 2 classes. I have only used the JSONReader class so far, and it seems to do its job well.

I had to make a few changes to fix a couple of issues, though. In case anybody runs into the same issues, here are my changes (in all their Unified Diff glory :)) –

Bugfix for infinite loop if a value is null, true or false –
@@ -81,13 +81,17 @@
} else if (c == 't' && next() == 'r' && next() == 'u' && next() == 'e') {
ret = Boolean.TRUE;
+ next();
} else if (c == 'f' && next() == 'a' && next() == 'l' && next() == 's' && next() == 'e') {
ret = Boolean.FALSE;
+ next();
} else if (c == 'n' && next() == 'u' && next() == 'l' && next() == 'l') {
ret = null;
+ next();
} else if (Character.isDigit(c) || c == '-') {
ret = number();
}

– System.out.println(“token: ” + ret); // enable this line to see the token stream
+// System.out.println(“token: ” + ret); // enable this line to see the token stream
+
token = ret;
return ret;

In JSONWriter. To fix the null pointer error, if the field has no getter or is inaccessible otherwise –

String name = prop.getName();
Method accessor = prop.getReadMethod();
- Object value = accessor.invoke(object, (Object[])null);
- add(name, value);
+ if(accessor != null) {
+ Object value = accessor.invoke(object, (Object[])null);
+ add(name, value);
+ }

Type conversion when using the ternary operator

What is the type of val in the following code?

boolean asInt = true;
Object val = asInt? 5 : 5.0;

If you guessed Integer, guess again. :)

JLS states –

if the second and third operands have numeric type, …. binary numeric promotion is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

If the second and third operands are of different reference types, then it must be possible to convert one of the types to the other type (call this latter type T) by assignment conversion ; the type of the conditional expression is T.

(Ref – JLS 15.25 Conditional Operator ? : )

I am sure I would have come across this while studying for my SCJP exam, but in real life, you rarely have objects of different types being returned from a ternary operator, so this can really catch you unguarded.

With an If-Else block, things work out as expected –

boolean asInt = true;
Object val = asInt? 5 : 5.0;
System.out.println("val is - " + val + " : " + val.getClass());
if (asInt) val = 5;
else val = 5.0;
System.out.println("val is - " + val + " : " + val.getClass());