Monthly archives "July 2014"

Spring Batch as Wildfly Module

posted by Roberto Cortez on

(TL;DR – Get me to the code)

For a long time, the Java EE specification was lacking a Batch Processing API. Today, this is an essential necessity for enterprise applications. This was finally fixed with the JSR-352 Batch Applications for the Java Platform now available in Java EE 7. The JSR-352 got it’s inspiration from the Spring Batch counterpart. Both cover the same concepts, although the resulting API’s are a bit different.

Since the Spring team also collaborated in the JSR-352, it was only a matter of time for them to provide an implementation based on Spring Batch. The latest major version of Spring Batch (version 3), now supports the JSR-352.

I’m a Spring Batch user for many years and I’ve always enjoyed that the technology had a interesting set of built-in readers and writers. These allowed you to perform the most common operations required by batch processing. Do you need to read data from a database? You could use JdbcCursorItemReader, how about writing data in a fixed format? Use FlatFileItemWriter, and so on.

Unfortunately, JSR-352 implementations do not have the amount of readers and writers available in Spring Batch. We have to remember that JSR-352 is very recent and didn’t have time to catch up. jBeret, the Wildfly implementation for JSR-352 already provides a few custom readers and writers.

What’s the point?

I was hoping that with the latest release, all the readers and writers from the original Spring Batch would be available as well. This is not the case yet, since it would take a lot of work, but there are plans to make them available in future versions. This would allow us to migrate native Spring Batch applications into JSR-352. We still have the issue of the implementation vendor lock-in, but it may be interesting in some cases.

Motivation

I’m one of the main test contributors for the Java EE Samples in the JSR-352 specification. I wanted to find out if the tests I’ve implemented have the same behaviour using the Spring Batch implementation. How can we do that?

Code

I think this exercise is not only interesting because of the original motivation, but it’s also useful to learn about modules and class loading on Wildfly. First we need to decide how are we going to deploy the needed Spring Batch dependencies. We could deploy them directly with the application, or use a Wildfly module. Modules have the advantage to be bundled directly into the application server and can be reused by all deployed applications.

Adding Wildfly Module with Maven

With a bit of work it’s possible to add the module automatically with the Wildfly Maven Plugin and the CLI (command line). Let’s start to create two files that represent the CLI commands that we need to create and remove the module:

wildfly-add-spring-batch.cli

The module --name is important. We’re going to need it to reference it in our application. The --resources is a pain, since you need to indicate a full classpath to all the required module dependencies, but we’re generating the paths in the next few steps.

wildfly-remove-spring-batch.cli

Note wildfly.module.classpath. This property will hold the complete classpath for the required Spring Batch dependencies. We can generate it with Maven Dependency plugin:

This is going to pick all dependencies (including transitive), exclude javax (since they are already present in Wildfly) and exclude test scope dependencies. We need the following dependencies for Spring Batch:

Now, we need to replace the property in the file. Let’s use Maven Resources plugin:

This will filter the configured files and replace the property wildfly.module.classpath with the value we generated previously. This is a classpath pointing to the dependencies in your local Maven repository. Now with Wildfly Maven Plugin we can execute this script (you need to have Wildfly running):

And these profiles:

(For the full pom.xml contents, check here)

We can add the module by executing:
mvn process-resources wildfly:execute-commands -P install-spring-batch.

Or remove the module by executing:
mvn wildfly:execute-commands -P remove-spring-batch.

This strategy works for any module that you want to create into Wildfly. Think about adding a JDBC driver. You usually use a module to add it into the server, but all the documentation I’ve found about this is always a manual process. This works great for CI builds, so you can have everything you need to setup your environment.

Use Spring-Batch

Ok, I have my module there, but how can I instruct Wildfly to use it instead of jBeret? We need to add a the following file in META-INF folder of our application:

jboss-deployment-structure.xml

Since the JSR-352 uses a Service Loader to load the implementation, the only possible outcome would be to load the service specified in org.springframework.batch module. Your batch code will now run with the Spring Batch implementation.

Testing

The github repository code, has Arquillian sample tests that demonstrate the behaviour. Check the Resources section below.

Resources

You can clone a full working copy from my github repository. You can find instructions there to deploy it.

Wildfly – Spring Batch

Since I may modify the code in the future, you can download the original source of this post from the release 1.0. In alternative, clone the repo, and checkout the tag from release 1.0 with the following command: git checkout 1.0.

Future

I’ve still need to apply this to the Java EE Samples. It’s on my TODO list.

Java EE 7 with Angular JS – CRUD, REST, Validations – Part 2

posted by Roberto Cortez on

This is the promised follow up to the Java EE 7 with Angular JS – Part 1. It took longer than I expect (to find the time to prepare the code and blog post), but it’s finally here!

The Application

The original application in Part 1 it’s only a simple list with pagination and a REST service that feeds the list data.

Java EE 7 - Angular - List

In this post we’re going to add CRUD (Create, Read, Update, Delete) capabilities, bind REST services to perform these operations on the server side and validate the data.

The Setup

The Setup is the same from Part 1, but here is the list for reference:

The Code

Backend – Java EE 7

The backend does not required many changes. Since we want the ability to create, read, update and delete, we need to add the appropriate methods in the REST service to perform these operations:

The code is exactly as a normal Java POJO, but using the Java EE annotations to enhance the behaviour. @ApplicationPath("/resources") and @Path("persons") will expose the REST service at the url yourdomain/resources/persons (yourdomain will be the host where the application is running). @Consumes(MediaType.APPLICATION_JSON) and @Produces(MediaType.APPLICATION_JSON) accept and format REST request and response as JSON.

For the REST operations:

Annotation / HTTP MethodJava MethodURLBehaviour
@GET / GETlistPersonshttp://yourdomain/resources/personsReturns a paginated list of 10 persons.
@GET / GETgetPersonhttp://yourdomain/resources/persons/{id}Returns a Person entity by it’s id.
@POST / POSTsavePersonhttp://yourdomain/resources/personsCreates or Updates a Person.
@DELETE / DELETEdeletePersonhttp://yourdomain/resources/persons/{id}Deletes a Person entity by it’s id.

The url invoked for each operations is very similar. The magic to distinguish which operation needs to be called is defined in the HTTP method itself when the request is submitted. Check HTTP Method definitions.

For getPerson and deletePerson note that we added the annotation @Path("{id}") which defines an optional path to call the service. Since we need to know which object we want to get or delete, we need to indicate the id somehow. This is done in the service url to be called, so if we want to delete the Person with id 1, we would call http://yourdomain/resources/persons/1 with the HTTP method DELETE.

That’s it for the backend stuff. Only 30 lines of code added to the old REST service. I have also added a new property to the Person object, to hold a link to image with the purpose of displaying an avatar of the person.

UI – Angular JS

For the UI part, I’ve decided to split it into 3 sections: the grid, the form and the feedback messages sections, each with its own Angular controller. The grid is mostly the same from Part 1, but it did require some tweaks for the new stuff:

Grid HTML

Nothing special here. Pretty much the same as Part 1.

Grid Angular Controller

A few more attributes are required to configure the behaviour of the grid. The important bits are the data: 'persons.list' which binds the grid data to Angular model value $scope.persons, the columnDefs which allow us to model the grid as we see fit. Since I wanted to add an option to delete each row, I needed to add a new cell which call the function deleteRow when you click in cross icon. The afterSelectionChanges function is required to update the form data with the person selected in the grid. You can check other grid options here.

The rest of the code is self-explanatory and there is also a few comments in there. A special note about $rootScope.$broadcast: this is used to dispatch an event to all the other controllers. This is a way to communicate between controllers, since the grid, form and feedback messages have separate controllers. If everything was in only one controller, this was not required and a simple function call would be enough. Another possible solution if we want to keep the multiple controllers, would be to use Angular services. The used approach seems much cleaner since it separates the application concerns and does not require you to implement additional Angular services, but it might be a little harder to debug if needed.

Form HTML

Here is the looks:

JavaEE 7 - Angular - Form

A lot of codeis for validation purposes, but lets look into this a bit more in detail: each input element binds its value to person.something. This allows to model the data between the HTML and the Javascript controller, so we can write $scope.person.name in our controller to get the value filled in the form input with name, name. To access the data inside the HTML form we use the form name personForm plus the name of the input field.

HTML5 have its own set of validations in the input fields, but we want to use the Angular ones. In that case, we need to disable form validations by using novalidate at the form element. Now, to use Angular validations, we can use a few Angular directives in the input elements. For this very basic form, we only use required, ng-minlength and ng-maxlength, but you can use others. Just look into the documentation.

Angular assigns CSS classes based on the input validation state. To have an idea, these are the possible values:

StateCSSOn
validng-validWhen the field is valid.
invalidng-invalidWhen the field is invalid.
pristineng-pristineWhen the field was never touched before.
dirtyng-dirtyWhen the field is changed.

These CSS classes are empty. You need to create them and assign them styles in an included CSS sheet for the application. Instead, we’re going to use styles from Bootstrap which are very nice. For them to work, a few additional classes need to be applied to the elements. The div element enclosing the input needs the CSS class form-group and the input element needs the CSS class form-control.

To display an invalid input field we add ng-class="{'has-error' : personForm.name.$invalid && personForm.name.$dirty}" to the containing input div. This code evaluates if the name in the personForm is invalid and if it’s dirty. It the condition verifies, then the input is displayed as invalid.

Finally, for the form validation messages we need to verify the $error directive for each of the inputs and types of validations being performed. Just add ng-show="personForm.name.$error.minlength" to an HTML display element with a message to warn the user that the name input field is too short.

Form Angular Controller

For the form controller, we need the two functions that perform the operations associated with the button Clear and the button Save which are self-explanatory. A quick note: for some reason, Angular does not clear input fields which are in invalid state. I did found a few people complaining about the same problem, but I need to investigate this further. Maybe it’s something I’m doing wrong.

REST services are called using save and delete from the $resource object which already implement the correspondent HTTP methods. Check the documentation. You can get a $resource with the following factory:

The rest of the controller code, are functions to pickup the events created by the grid to load the person data in the form and delete the person. This controller also create a few events. If we add or remove persons, the grid needs to be updated so an event is generated requesting the grid to be updated.

Feedback Messages HTML

This is just the top section of the application, to display success or error messages based on save, delete or server error.

Feedback Messages Angular Controller

This is the controller that push the messages to the view. Listens to the events created by the grid and the form controllers.

The End Result

Uff.. that was a lot of code and new information. Let’s see the final result:

JavaEE 7 - Angular - Full

There is also a live version running in http://javaee7-angular.radcortez.cloudbees.net, thanks to Cloudbees. It may take a while to open if the cloud instances is hibernated (because of no usage).
Unfortunately, Cloudbees stopped application hosting, but you can try using Codenvy in the following URL: https://codenvy.com/f?id=3qe4qr7mb8i86lpe. Check the post: Codenvy setup to demo applications using Docker: Java EE 7 with Angular.

Resources

You can clone a full working copy from my github repository and deploy it to Wildfly. You can find instructions there to deploy it. Should also work on Glassfish.

Java EE – Angular JS Source

Since I may modify the code in the future, you can download the original source of this post from the release 3.0. In alternative, clone the repo and checkout the tag from release 3.0 with the following command: git checkout 3.0.

Check also:

Final Thoughts

  • The form validation kicks in right after you start typing. Angular 1.3 will have an on blur property to validate only after loosing focus, but I’m still using Angular 1.2.x.
  • I have to confess that I found the validation code a bit too verbose. I don’t know if there is a way to simplify it, but you shouldn’t need to add each message validation to each input.
  • A few things are still lacking here, like parameters sanitisation or server side validation. I’ll cover those in a next blog post.

This was a very long post, actually the longest I’ve wrote on my blog. If you reached this far, thank you so much for your time reading this post. I hope you enjoyed it! Let me know if you have any comments.

Fifth Coimbra JUG Meeting – Spring MVC

posted by Roberto Cortez on

Last Wednesday, 16 July 2014, the fifth meeting of Coimbra JUG was held on the Department of Informatics Engineering of the University of Coimbra, in Portugal. The attendance was very good, we had around 30 people to listen João Antunes talk about the Web Framework – Spring MVC. A very special thanks to João for taking the challenge and steer the session.

This topic continues a long list of Web Frameworks planned to be presented at Coimbra JUG. Have a look into the most wanted sessions pool, and cast your vote if you’re a member.

Coimbra JUG Meeting 5 Audience

I did a quick introduction about Coimbra JUG for the newcomers and João dived right into the session about Spring MVC. Spring MVC is not exactly a new technology, but only one or two attendees were using it. The rest of the attendees seemed very curious and interested to learn about it.

Looking into RebellabsJava Tools and Technologies Landscape for 2014, Spring MVC appears at 1st place for the Web Frameworks in use with a 40% share. A huge percentage, which means that is very likely for you to como across with it in the future.

As always, we had surprises for the attendees: beer and chocolates, if you participated in the discussion. IntelliJ sponsored our event, by offering a free license to raffle among the attendees. Congratulations to João Baltazar for winning the license. Develop with pleasure! We also offered the book The Definitive Guide to HTML5 WebSocket courtesy of Kaazing, congratulations to Jessica Vicente. Finally, we gave away two Atlassian Stash t-shirs: “Just Do GIT” to Mário Homem and João Almeida.

Here are the materials for the session:

Enjoy!

Code Development Estimation

posted by Roberto Cortez on

Today, I have published a new article: Why it’s challenging to make estimations about code (plus a developer puzzle) on RebelLabs. I am involved a lot in project estimations, for proposals evaluations, project planning and code development. In my opinion, developers have a hard time estimating the work they need to perform a needed task. Hopefully this article will shed some light in the art of estimation.

Estimation

A special thanks to RebelLabs for letting me publish my work there and of course to Oliver White for all the support on writing and reviewing the article. You rock!