FAQ for Freelancers

posted by Roberto Cortez on
tags:

Freelancer Code for FoodI’m now working as a Freelancer for more than a year and I think it’s time to write about it again. I previously wrote about Five Ways to Not Suck at Being a Java Freelancer and I even delivered a quick session at Geecon. There is no video yet (should be released soon), but the slides are available.

Anyway, I do get asked a few questions that are not covered in the article or the presentation, so I had the idea to write this post and share my vision as a FAQ. The questions are in no particular order and they reflect my personal experience and should not be treated as an absolute truth.

How do you get clients?

There is no single source to look at. My first client was my previous company. It may look weird, but it was good for everyone. They already knew me and they didn’t have to spend resources looking for other professionals. For me, I was already identified with the company work methods and knew everyone. It was a great way to start.

My next client approached me on LinkedIn. It’s truth that you get a lot of requests and most of them are not interesting, but you only need one to make it worth it. Create a LinkedIn profile and keep it updated and clean. You might get the opportunity that you are looking for.

You can also obtain clients with business cards and colleagues / friends references. Do not underestimate their power. You never know when you are going to bump into someone that has a problem that you can fix (or your colleagues / friends). I was also able to get a few this way.

I do stay away from the platforms that sell you freelance jobs. There is too much competition there, and I prefer to create long time relationships with my clients.

How do I charge my clients?

You should take into account a few factors: the client location, the market in which he operates and your experience with the task in hands.

If you only have 1 year experience with Android, you cannot charge as much as if you have 8 years experience with Java EE. You can usually charge higher for clients operating in the finance sector, but be aware of location. Portugal for instance has very low rates, but in Ireland these are much higher.

It’s fine to charge an hourly or daily rate with different values. Just remember that you and your client must both be comfortable with the rate or you end up risking the business relationship since one of you could become unhappy.

How do you plan the work?

Clients just tell me what they need and I estimate how much time do I need to complete the task. They might not agree with my estimation so you should negotiate with them. Have a look into an post I wrote about estimations: Why it’s challenging to make estimations about code.

What if you exceed you estimation?

First of all, you need to understand why did that happen. Were you very optimistic in the estimation? Did the client provide you with all the information you needed? Or maybe the client added a few extras after the original estimation?

Sometimes you are going to make mistakes and you need to work a few extra hours to finish the work without any extra compensation. No matter what, always be transparent with your client and share everything with him. He will surely understand and help you out.

In other occasions, this will be the client responsibility. You need to negotiate with him, and share with him the possible delays and adjust your estimation and/or price.

How do you deal with multiple clients?

Having multiple clients does not mean that you are working for all at the same time. Important thing here is planning. If they ask you something and you are already occupied, there is no harm in declining. It’s better than accepting multiple tasks and not being able to deliver them properly.

You can always try to postpone the tasks by negotiating with your client. It depends a lot on your client schedule, but if you can pull it off it helps you keep your pipeline for the future.

Do you work in a team?

Yes, most of my work is with a team. In today’s world is hard to do something alone, so it’s only natural to work with other people. I don’t feel that I’m treated differently just because my contractual situation is different. I’m just another member of the team doing my job.

Where do you work?

I work from home most of the time, but I usually go to the client facilities from time to time. For me is important to be able to work remotely due to some personal issues. Clients may not allow you to do that, but you can always propose to work for a few months in their office. When everyone feels comfortable you can switch to remote and return from time to time.

How do you communicate with your clients?

I usually use Skype, Mail and Phone. In these days, there is no reason for not being in constant contact.

How do you deal with timezones?

Since I manage my own schedule, I can always find a suitable time to communicate with my clients, no matter the timezone. Of course it might require you to be available very early or very late.

Do you have a life?

I do! I usually work a regular work week of 40 hours. Sometimes I can work a bit more. The important thing here is to plan your schedule very well, so you can have time for everything.

Missing a question? Feel free to ask it in the comments sections and I’ll be glad to answer it!

Maven Git Release

posted by Roberto Cortez on
tags: ,

I need to start this post by stating that I’ve only started to work seriously with Git within the last year. Unfortunately, a lot of the projects that I work on are still using SVN or CVS, but I’m now finally starting in a few that use Git.

During the last few years, I’ve done a lot of software releases using Maven Release Plugin. I still remember that I’ve took a full week just to setup the plugin in one of my projects. It worked well most of the times, but if something went wrong you could spend the next few hours fixing the problem. Oh boy, what a nightmare!

Recently, I wanted to do the same operation with a Git project and I came across with the Maven JGit-Flow Plugin and I have to tell you that this is fantastic! Very easy to setup and worked flawlessly on the first try!

This plugin is based on the development model described in the post A successful Git branching model by Vincent Driessen. Take your time to read it, since it’s very interesting.

I’m going to show you how to perform a release using this plugin. I’ll use the project from my latest post about Spring Batch as Wildfly Module.

Setup

Setup is very easy, just add the following to your pom.xml:

I’ve just added the noDeploy configuration, because I’m not releasing to a Maven repository. That’s it!

Release

Let’s look at my project branches and version:

Now, just run mvn jgitflow:release-start:

You get an interactive menu to pick the version numbers you want to release, the same way as Maven Release Plugin. I’m developing on the master branch, but during this process a release branch is created with the release versions and development branch with the new development versions.

Now the cool thing about this, is that everything is still in your local environment! If you are not happy with the changes, you can get rid of the branches and start over. No build was performed at this point.

If we want to release, just run mvn jgitflow:release-finish:

In this step, the release branch is going to get merged as described in A successful Git branching model and create the tag. Remember, nothing has been pushed yet, so you can always revert the process.

Let’s have a look into the branches and tags now:

Now you’re a push away to complete your release and ready to keep developing in your new updated development branch. How easy was that?

Conclusion

Looking into some differences between the original release plugin and jgitflow:

  • You don’t have to worry about stage commits. Everything is local until you push.
  • No more problems with other people changing pom.xml during the process.
  • Your project is only built once, saving release time.
  • Very easy to setup. Everything is picked from your Git configuration.

When I was investigating / writing, I’ve found this very interesting post, about an alternative way to perform the release. It’s worth reading: http://axelfontaine.com/blog/final-nail.html by Axel Fontaine

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!