Pages

Tuesday, October 22, 2013

I just finished reading a book Understanding SCA (Service Component Architecture) that covers SCA in detail. The book is a topic for another post. I did come across a gem in the book around Dependency Injection (DI) techniques, and how to make choices around one technique over another.

The three main techniques used for Dependency Injection (DI) are constructor, setter, and field injection. There is also reflection which I will not discuss in this article.

Constructor Injection

This technique calls for injecting the objects used in our class at object instantiation. A significant advantage of this technique is that it makes all of our dependencies explicit at compile time. This also makes testing much easier since we can use testing techniques like mock objects to test. "... Constructor-based injection also enables fields to be marked as final so they cannot be inadvertently changed later on." This can also add some additional performance gains since the object are final and the compiler can optimize this. If you allow mutators for the objects injected, then this performance perk is negated since the object can not be marked final.

A disadvantage of constructor based injection is that the constructors parameter lists can become very large. I would recommend that this approach be considered for 4 parameters, or less. Four parameters can result in 16 test cases (n X n matrix). Additionally, there may be more than one constructor, and dependency injection frameworks deal with it differently. Weld currently only allows DI on one constructor.

Advantages

Disadvantages

Explicit Dependencies at compile time.

Constructors can become very large

Fields can be marked final

Mutable fields lose final advantage

Testing can be simplified

The number of parameters produces an n X n matrix of tests

Setter Injection

The next technique is using setter based injection. Typically we have an object with setters and getters where the setter is annotated for injection. This requires that our setters be public, or protected. I would recommend making them public in the absence of reasons to do otherwise. The significant advantage to setter based injection is the ability to change the injected object at runtime. If the method is public, then it can be changed by any object. This could be an advantage, or disadvantage. Also this technique is conducive to testing as well. We can inject mock objects, or use a framework like Arquillian to handle injection during testing.

The disadvantages of using setter based injection "... are two major disadvantages to setter injection. Component (Class) dependencies are dispersed across a number of setter methods, making them less obvious and increasing the verbosity of the code because a method needs to be created for every reference In addition, setter methods make references that should be immutable subject to change because the fields they are assigned cannot be declared final." The second item may not be a disadvantage if considered closely in your design. The former represents a significant disadvantage in terms of code clarity that has been a hallmark of EE5/6/7.

Another item to consider is that the one of the best practices for developing interfaces is to avoid putting setters in them. Interface design usually only has the getter defined, the setter is an implementation detail that is left out of the contract. This prevents the client code from altering the implementation code accidentally since it should be interacting with the interface contract.

Advantages

Disadvantages

Code is more testable

Results in less readable code as the number of references increase.

Injection can be changed at runtime.

Fields cannot be marked final

-

Mutators (setters) are typically not part of the interface contract.

Field Injection

Field based injection is often used in example code found for Dependency Injection (DI) frameworks. "The major advantage of field-based injection is that it is concise." The fields may be public, private, protected, or default. They can not be marked final. This technique avoids large lists of parameters for constructors, and adding setter methods that are not part of the interface contract. The Major disadvantage is unit testing. You need to add a setters, sub-class the object, or use reflection typically. A framework like Arquillian can be used to test, but this adds additional complexity that would not be required for using constructor, or setter injection. The brevity is both an advantage and disadvantage.

Advantages

Disadvantages

Concise

Difficult to test

-

Fields cannot be marked final

Summary

In examining the tables of advantages and disadvantages, you may come to a conclusion that Field injection may be the best choice. This would be premature. In fact, there is clearly no one technique that is better than the other. All have advantages, and disadvantages. Clearly as a developer, or architect you must decide for a given class, or set of classes which technique will meet your requirements. A lot has been said about picking a pattern, and using it consistently throughout your project. I personally find that idea bad. Comparatively, we could say it is like picking a hammer out of a toolbox and using nails everywhere. Sometimes a bolt and nut would work much better. Don't fall into the trap of consistency over what makes sense for your project.

Tuesday, October 15, 2013

Introduction

We are finishing up a release cycle at work. We have switched from Clearcase to Mercurial, and from a home grown bug tracking system to JIRA. We just released our latest software release on Monday, and its time to clean up the repo and JIRA.

Here is the situation. We chose for this release iteration to use a JIRA issue per branch approach. This worked for our situation where we had a number of new users to Mercurial, and JIRA. We could easily manage any issues with the build, or user mistakes. We will re-think the approach now that our team are up to speed on Mercurial.

We also implemented a server side Mercurial trigger that checked if the JIRA issue was assigned to the committer (person pushing to "master" repo). If not, they would not be able to push to the server. That way we could make sure that there were issues associated with check-ins.

So far, I think we did a good job since we yanked the rug from under the staff. QA finished their process and marked all of the JIRA issues closed. However, they don't have permissions to modify Mercurial to close the branches. That makes sense because they should be testing and not writing code. Now it is time to pay the piper.

We needed a mechanism to read the JIRA issues, look for the closed issues, assign them to a primary committer on JIRA with permissions on Mercurial, close the branch, and push to update the issue with a JIRA comment from the Mercurial check-in trigger. Got that?

Lets try that again...

Read the JIRA issues and find all CLOSED issues.

Read all of the Mercurial branches that are not closed. Remember the branches have the same name as the JIRA issue.

Assign the JIRA issue to a primary committer.

Switch to the branch and update

Close branch and commit

Push to "Master" server. This will not work unless the issue is assigned to primary committer since it has a commit trigger.

The commit will update JIRA with the closed branch commit comments.

Are you still with me?

The code we wrote to do most of the work is proprietary. However, one aspect of it is worth sharing with the community. How do you assign a JIRA ticket to another user using the JIRA REST interface. The code below demonstrates how to do that.

Code

IssueAssignmentClient.java

App.java

Tuesday, October 08, 2013

I was testing some additional functionality that is available for security on Java EE 6 and EE 7 platforms. One item that is extremely important for all developers is avoiding Cross-Site Scripting (XSS) issues. This can normally be handled very easily by adding http-onlyto your web.xml configuration.
This works on most application servers. More on that later.
Additionally, you may will likely only want to set the JSESSIONID to be a cookie to prevent the cookie information being placed in the URL. This is accomplished by adding tracking-mode to to your web.xml configuration.
This is again a common sense approach that has been mentioned in a number of publications, and articles. However, this simple EE 6 configuration did not work for me on IBM WebSphere. There is a security mechanism called "Programmatic session cookie configuration" that prevents the JSESSIONID cookie from being modified. I found that I could re-name the JSESSIONID for the application in the web.xml to get around this restriction. Here is my new configuration with a nod to the NSA:
When I made the changes, everything worked as expected, but I wanted to make sure when my session is invalidated that I clean up my "NSA" tracks. So I created a new logout method for my JSF based application.

Sunday, October 06, 2013

I mentioned in my panel discussion for Cool NetBeans Tips and Tricks for Java EE 7 Development that I would publish my 6:30 demo for creating an application from nothing to PrimeFaces application on GlassFish 4.0.

Introduction

I attended a talk at JavaOne 2013 on Expression Language 3.0. It was a great talk by Ed Burns and Kin-man Chung about EL. EL 3.0 has been modular for a while, and can operate independently of the EE platform. I knew that, but this was a siren call reminder of that fact. During the talk, I asked a number of questions and for clarifications. One interesting clarification was that EL 3.0 was compiled using Java 7. This was following a discussion of the fact that it supports Lambda expressions. Wait... it uses Lambda expressions from Java 8 and is compiled using Java 7. I asked could it be compiled on Java 6. Kin-man Chung, the specification lead, told me that with some minor changes; "it should?" I took that as a challenge to try. I was successful and now I can do Lambda expressions on JDK 6.

When I mentioned that I was using this technique for Java 6 on Twitter, Michael Graciano pointed out that +Adam Bien had done something similar for Java 1.7. I am not sure if great minds think alike, or fools seldom differ on this one, but his article is a very cool read too.