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.
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!
I was in London between 12 and 13 June to attend the second edition of Devoxx UK. The conference was first scheduled to take place in April, but was later moved on to June. I guess it was a good call, since it was so close in dates to Devoxx Paris (that was also held in April) and they would probably overlap. I submitted a few sessions for Devoxx UK, but unfortunately they were not selected. I have to confess that since I was not selected I was not planning to go, but I’m getting conference addicted and the next conference I have scheduled is JavaOne 2014 in late September (where I’m going to speak). I realised that I couldn’t stay so much time without attending something, so I decided to signup just a few days before the conference started.
Venue
The Business Design Centre is a venue which houses exhibitions and consumer fairs and was also the place for Devoxx UK. The conference was only occupying a small fraction of the total venue capacity. We did not have the cinema like rooms from Devoxx BE, but the rooms were nice, the Exhibition Hall was well designed and there was also another floor for the community activities: Hackergartens, BOF sessions and hands-on-labs. Unfortunately, both the Exhibition Hall and the Community Hall were very warm in my opinion, good only to be on a beach or pool with a cold drink on the side.
Sessions
The program was interesting enough, a lot of diverse subjects and you had four options to attend on each scheduling bracket. I was not always into sessions, since I also wanted to spend some time in the Exhibition and Community Halls. Not a problem, because all the sessions were recorded and are going to be available on Parleys, which is cool. Devoxx UK kicked-off with a very inspirational keynote by Dan North about building a career and the interactions that impact you and the ones around you. I advice you to check it out when the video is available. These are my top 3 sessions (from the ones I have attended):
Unfortunately, there were also a couple of negative things. One of the sessions that I really wanted to attend the speaker didn’t show up, and in another the speaker arrived really late. I even considered jumping in and replace the missing speaker, but I didn’t have my laptop and I was not sure if the organization or the other attendees would enjoy the idea 😀 .
Food
Call me weird, but I really need hot meals for lunch and dinner. The Devoxx food, and not only in the UK (it was the same in BE, I don’t know about FR), it’s bad for my taste, so I ended up going outside for some food. Idea: There is no need to have something fancy, just get some chicken and charcoal and you can have a pretty tasty roasted barbecued chicken. I can even do it myself!
Community
The Community was awesome as always! This is now starting to be one of the mains reasons that make me want to attend more and more conferences. Once again a contributed a few little bits of code for the Java EE 7 Samples in the Hackergarten with Heather VanCura, Arun Gupta, Peter Pilgrim and Andres Almiray.
I was also able to bring a few goodies to offer in the next Coimbra JUG Meeting. Thanks to Kaazing and JCP.org for the books they offered and Atlassian for the t-shirts.
It was great to meet again a few guys (and girls) from others events (in no particular order):
And a special thanks for Peter Pilgrim for giving me a signed copy of his Java EE 7 Developer Handbook. Congratulations Peter, for the huge job that is to write a book!
Next Devoxx UK
Devoxx UK is returning again in 2015, and now with 3 days instead of 2 (running from 17 to 20 June of 2015). I’m submitting again for 2015 and I’m positive that I will have something selected next year!
Yesteday I got really great news. I was selected to present 3 out of 4 sessions that I have submitted to JavaOne 2014! After attending the first JavaOne in 2012, and going again in 2013, this was my first time submitting something for JavaOne.
I have to confess that I had high hopes of being selected, but I was not expecting to have 3 sessions right in the first year of submissions, since there are a lot of submissions and it’s really hard to get selected. A special thanks to Reza Rahman for helping me out during the submission process and for providing valuable tips. Thanks Reza! I would also like to thank you Ivan Ivanov and Simon Maple my co-speakers in two of the sessions.
Have a look below into the sessions abstracts and videos. I don’t have the schedules yet, but look for them in the JavaOne Schedule Builder (when available) and signup 🙂
What am I going to speak about?
CON2818 – Java EE 7 Batch Processing in the Real World
Abstract
This talk will explore one of the newest API for Java EE 7, the JSR 352, Batch Applications for the Java Platform. Batch processing is found in nearly every industry when you need to execute a non-interactive, bulk-oriented and long running operation task. A few examples are: financial transactions, billing, inventory management, report generation and so on. The JSR 352 specifies a common set of requirements that every batch application usually needs like: checkpointing, parallelization, splitting and logging. It also provides you with a job specification language and several interfaces that allow you to implement your business logic and interact with the batch container. We are going to live code a real life example batch application, starting with a simple task and then evolve it using the advanced API’s until we have a full parallel and checkpointing reader-processor-writer batch. By the end of the session, attendees should be able to understand the use cases of the JSR 352, when to apply it and how to develop a full Java EE Batch Application.
Abstract
We all enjoy to hear a good success story, but in the software development industry the life of a developer is also made up of disasters, disappointments and frustrations. Have you ever deleted all the data in production? Or maybe you just run out of disk space and your software failed miserably! How about crashing your server with a bug that you introduced in the latest release? We can learn with each others with the mistakes we made. Come to this BOF and share with us your most horrific development story and what did you do to fix it.
CON4255 – The 5 people in your organization that grow legacy code
Abstract
Have you ever looked at a random piece of code and wanted to rewrite it so badly? It’s natural to have legacy code in your application at some point. It’s something that you need to accept and learn to live with. So is this a lost cause? Should we just throw in the towel and give up? Hell no! Over the years, I learned to identify 5 main creators/enablers of legacy code on the engineering side, which I’m sharing here with you using real development stories (with a little humour in the mix). Learn to keep them in line and your code will live longer!
When I was writing my previous post about Java EE and Angular, I was overwhelmed with all the javascript files that I needed to include in my application to implement the behaviour that I was looking for. OK, not that many scripts actually, four in total: Angular JS (Angular also requires jQuery), ng-grid and UI Bootstrap. Unfortunately, it was not so simple. Each script, may also need a CSS file and some of the scripts depended on different versions from each others. Finally, I also needed to include all the files in my index.html. For that particular post, I ended up doing everything manually and it was a real pain. There must be a better way!
The Problem
In Java, whether you like it or not, Maven is the number one tool to perform this kind of management, but what about Javascript? I’m far from an expert, so after asking our friend Google about it, I was a bit surprised with the amount of existent tools to do the job and for a newcomer this seemed complicated and lacking a common solution generally accepted by the community. Here are a couple of interesting posts about the problem:
I was not exactly sure which tool should I use, so after a few talks with a couple of colleagues that were working in Javascript applications they recommended NPM-Bower-Grunt combo:
Grunt is a task-based command line build tool for JavaScript projects.
Both Bower and Grunt are Node.js packaged modules and we only need NPM to download them. Bower is going to be responsible to download and manage all the javascript dependencies for our web application. Finally, Grunt will automate the task for adding the correct tags to the html files. Actually, Grunt also have tasks to concatenate and minify multiple files in a single one. This is useful to improve the performance of your application in production environments, but it was not may main focus.
The Setup
Paulo Grácio, a very good friend of mine that I work with, was kind enough to pick up my Java EE Angular sample on Github and setup everything needed to provide the application with Javascript Package Management. Thank you so much Paulo!
Maybe it’s a stupid comparison, but I’ll try to establish parallels with Java Maven build, to help people like me that are used to Maven to better understand what’s going on.
Install NPM
The pre-built installer of Node.js is all you need to have NPM up and running on your machine, but I actually followed this post to install NPM using Homebrew on OS X.
Now we need a package.json file in the root project folder. We are using this one:
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"name":"javaee7-angular",
"version":"1.0.0",
"authors":[
"Roberto Cortez <radcortez@yahoo.com>",
"Paulo Grácio <paulo.gracio@gmail.com>"
],
"description":"javaee7-angular dependencies for Grunt.",
"private":true,
"devDependencies":{
"load-grunt-tasks":"~0.6.0",
"time-grunt":"~0.4.0",
"grunt-contrib-clean":"~0.5.0",
"grunt-wiredep":"~1.8.0",
"grunt-contrib-htmlmin":"~0.3.0",
"grunt-usemin":"~2.3.0",
"grunt-contrib-copy":"~0.5.0",
"grunt-contrib-concat":"~0.4.0",
"grunt-contrib-uglify":"~0.5.0",
"grunt-contrib-cssmin":"~0.9.0",
"grunt-bower-install-simple":"~0.9.3"
},
"engines":{
"node":">=0.8.0"
}
}
In this file, you can find the node settings for your project. The most interesting stuff here is the devDependencies definition. Here you can find the Grunt task to download the project dependencies (grunt-bower-install-simple) and the task to inject the scripts and css in the index.html (grunt-wiredep). This is similar to the plugins definitions in a Maven pom.xml file. Running npm install should download everything you need to start using Grunt and the project tasks.
Managing Web Packages with Bower
Now we need to tell Bower which packages we want to include in the project. Add a file named bower.json in the root project folder:
Remember the original problem? Manage Angular, jQuery, ng-grid and UI Bootstrap dependencies? Here we have the definitions. I can compare it again like being a bit similar to the dependencies section in a Maven pom file for a Java project. Just a small detail, Bower uses Convention-over-Configuration to define project paths. This is important because the default location to download the javascript packages does not follow the Maven folder layout, so we should change Bower path to match Maven web app layout. To fix this, we need to add a file named .bowerrc to the project root folder:
.bowerrc
1
2
3
{
"directory":"src/main/webapp/lib/bower"
}
Defining Grunt Tasks
To glue everything together, we use Grunt to run the different tasks, but first we need to add another file to the project root folder, Gruntfile.js:
Gruntfile.js
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
'use strict';
module.exports=function(grunt){
// Load grunt tasks automatically
require('load-grunt-tasks')(grunt);
/*
* Time how long grunt tasks take to run, this might be important when having complex builds that take forever.
* For now just to show how fancy grunt is.
*/
require('time-grunt')(grunt);
// init required configurations for each task.
grunt.initConfig({
// Project settings
config:{
path:{
webapp:{
root:'src/main/webapp'
},
temp:{
root:'temp'
},
build:{
root:'build'
}
}
},
// From grunt-contrib-clean
clean:{
build:[
'<%=config.path.temp.root%>',
'<%=config.path.build.root%>'
]
},
// From grunt-bower-install-simple. Downloads the web dependencies.
"bower-install-simple":{
options:{
color:true,
production:false
}
},
// From grunt-wiredep. Automatically inject Bower components into the HTML file
wiredep:{
target:{
src:'<%=config.path.webapp.root%>/index.html',
ignorePath:'<%=config.path.webapp.root%>'
}
},
// From grunt-contrib-copy. Copies remaining files to places other tasks can use
copy:{
build:{
files:[
{
src:'<%=config.path.webapp.root%>/index.html',
dest:'<%=config.path.build.root%>/index.html'
}
]
}
},
// From grunt-contrib-htmlmin. Minifies index.html file.
htmlmin:{
prod:{
options:{
collapseBooleanAttributes:true,
collapseWhitespace:true,
removeComments:true,
removeCommentsFromCDATA:true,
removeEmptyAttributes:true,
removeOptionalTags:true,
removeRedundantAttributes:true,
useShortDoctype:true
},
files:[
{
expand:true,
cwd:'<%=config.path.build.root%>',
src:['index.html'],
dest:'<%=config.path.build.root%>'
}
]
}
},
// From grunt-usemin. Reads HTML for usemin blocks to enable smart builds
useminPrepare:{
html:'<%=config.path.webapp.root%>/index.html',
options:{
staging:'<%=config.path.temp.root%>',
root:'<%=config.path.webapp.root%>',
dest:'<%=config.path.build.root%>'
}
},
// From grunt-usemin.
usemin:{
html:'<%=config.path.build.root%>/index.html'
},
// From grunt-contrib-uglify.
uglify:{
options:{
mangle:false
}
}
}
);
// Task: Build production version ready for deployment
grunt.registerTask('build',[
'clean:build',
'bower-install-simple',
'wiredep',
'useminPrepare',
'concat:generated',
'cssmin',
'uglify',
'copy:build',
'usemin',
'htmlmin'
]);
grunt.registerTask('default',[
'build'
]);
};
For this file, we are just adding configurations to each Grunt task. We can also assemble all the tasks together to run in our own defined task named build or default. This is like defining our own Maven build lifecycle (which is not possible in Maven) and configuring the plugins settings. So, we actually have plugins (tasks) definitions in one file (package.json) and plugins (tasks) settings in a separate file (Gruntfile.js).
There is one more thing to do: we need to add a few special placeholders into our HTML files so that the Grunt tasks can add Javascript and CSS files automatically, based on Bower dependencies. For this project we have an unique index.html file and the head section should look like this:
The <!-- bower:css --> marks the location in the html file where the css files dependencies must be inserted and <!-- build:css css/third-party.css --> is used to indicate the merged file with all the css code. For <!-- bower:js --> and <!-- build:js lib/third-party.js --> it works the some way. Note that we have separated the external files from the own application files.
Final Structure
The project structure result is the following:
Executing Grunt Tasks
After all this setup, we are finally ready to execute Grunt tasks and have our web files managed! So, going from the start, we execute from the command line in the project folder root:
npm install
followed by
npm install -g grunt-cli
finally
grunt
You will notice the following:
A node_modules folder is created with all of the Bower and Grunt dependencies.
A src/main/webapp/lib/bower folder is created with all of the web application dependencies (Angular, jQuery, ng-grid and UI Bootstrap).
The src/main/webapp/index.html file is injected with the needed Javascript and CSS files.
A build folder is generated with an optimised version of the web application (files concatenated and minified).
The end result:
You can also execute individual Grunt tasks:
grunt bower – Downloads the web application dependencies. grunt bowerInstall – Modifies and inject the required files in your index.html.
Resources
You can find the updated Java EE 7 – Angular JS example with Javascript Package Management in Github, here. For the moment it’s in a branch but we intend to merge it with the original example.
Update In the meanwhile I have merged this code with the original example. Please, download the original source of this post from the release 2.0. You can also clone the repo, and checkout the tag from release 2.0 with the following command: git checkout 2.0.
Final Thoughts
Uff! It was not easy to do this. A lot of files to add and to configure and a lot of tools to study. Maybe there is an easier way to accomplish the same using other existent setups and tools in the Javascript landscape. I cannot tell you this is the best, since I would have to setup all the other solutions around the Javascript landscape, but this is a possible approach and it works. Just a couple of weeks after working on this, I found the following:
Don’t get me wrong, but I feel that the Javascript landscape is popping build tools like mushrooms. In my opinion it would be better to have a single standardised tool that everyone could use. Let’s see what is going to happen in the future.
Probably it could also be easier to use Yeoman to generate the structure, but we also wanted to learn more about the individuals tools, and I think you learn a bit more by doing things manually the first couple of times.
A Special Thanks
To Paulo Grácio for updating the Java EE 7 – Angular JS sample with all this setup! Thank you Paulo!
Last Thursday, 22 May 2014, the fourth 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 Paulo Martins talk about the Web Framework – Google Web Toolkit. A very special thanks to Paulo for taking the challenge and steer the session.
I did a quick introduction to the group to welcome the newcomers and Paulo dived right in the session about Google Web Toolkit. GWT is not exactly a new technology, but I think that the topic draws some interest since I know a lot of people using it in their projects, and looking into Rebellabs – Java Tools and Technologies Landscape for 2014, GWT appears at 4th place for the Web Frameworks in use with a 10% share. Only a few people in the audience used GWT before, but there was a lot of interest to learn a little about it. Paulo presented some of the most relevant topics about GWT and show cased a few examples with live code demos.
For this meeting, Paulo had a surprise for the attendees: beer and chocolates. Thanks for Praxis Brewery for proving the beer! IntelliJ also sponsored our event, by offering a free license to raffle among the attendees. Congratulations to Bruno Martins for winning the license. Develop with pleasure!