Tag Archives: configuration management

Keeping Confidential Information Out Of Git

I’ve launched yet another open source project on GitHub a couple of months ago and now it’s time to use it in production. For that, I had to put some confidential information in a file that is currently tracked by Git. That was the database connection credentials that I keep in a property file. Obviously, I couldn’t push that file to GitHub and I did’t want to keep that file in my staging area forever, but I still wanted to keep the file in the repository, so people could use it to configure their own development/production databases as well.

The file I’m talking about is usi4biz/resources/db-config.edn. Notice that I’ve put pretty dumb credential information there just to make it work in my development environment. This file doesn’t exist anymore in the master branch. I had to do a little tweak, inspired by WordPress, to address the issue.

Before adding any confidential info, I renamed the file to db-config-example.edn:

$ git mv resources/db-config.edn resources/db-config-example.edn
$ git add resources/db-config-example.edn
$ git commit -m "Renamed the database configuration file"

Then, I copied the file and named it after the original name:

$ cp resources/db-config-example.edn resources/db-config.edn

I edited the new file and added the production credentials. Now, I just have to ask Git to ignore it:

$ echo -e "resources/db-config.edn\n" >> .gitignore

This way, db-config.edn will be always out of my staging area whenever I change it. I just have to remember that if I ever need to add a new property I have to do it in both files. For the moment, I just explained in the README file that those wiling to use the application have to copy the file db-config-example.edn with the name db-config.edn because the code refers the file db-config.edn.

TomEE-CLI: An Alternative To Manage TomEE

About a year ago, when I was looking for alternatives to replace our Glassfish servers (why?), I had the chance to evaluate TomEE. Talking to TomEE’s team was indeed a pleasant experience. By far, the best support you can get from a JavaEE player. Just to give you an idea, they replied all questions in less than 24 hours, while we had to wait over a month to get the first feedback from RedHat about JBoss EAP. We had multiple evaluation criteria and, unfortunately, TomEE didn’t go well in the management part. JBoss offered redundant ways to manage the server, including a web API, a command line tool and a web console. Since the infrastructure team put too much weight on the management aspect, I had to agree and formally recommend JBoss EAP. Sometimes, we have to make unpleasant decisions, but that’s business.

As an open source enthusiast, I knew I needed to do something to help TomEE. So, I thought about contributing to the documentation but I had to step back because my daughter had just been born at the time. Looking at my GitHub profile, one can see how much of my free time was filled up with paternity love. The good news is she is growing fast and becoming less demanding, leaving some room for my open source projects.

github-contributions

In January this year, when my brain left hemisphere was in good shape again, I decided to learn Clojure, a functional programming language on the JVM. I’ve got so excited that I started telling my friends about what I would describe as a “mind-blowing experience”. One of them, Daniel Cunha, was particularly excited about that. We were talking all the time about infinity possibilities we have at hands with Clojure. Then he suddenly came out with a project proposal I couldn’t refuse: “Let’s write a client tool for TomEE. I’m trying to write one in Java, but it’s taking too long. Let’s write it in Clojure”. And then I said “Yesss! Of course”. Daniel didn’t realise but he was giving me the chance I was looking for: solving exactly the point where TomEE didn’t do well in our analysis. I’m sure Daniel didn’t expect such enthusiasm coming from a contributor.

On April 13th 2015 we released the first version of TomEE-CLI. We started our endeavour in Mars 9th and we managed to develop 11 functionalities within a month with just 300 lines of code. No doubt Clojure and its ecosystem has made it possible. Can you imagine what we can achieve within a whole year?!

How It Works

We basically developed a Clojure API to manage TomEE instances. This API is so simple that you don’t even need to learn Clojure to use it. Clojure’s syntax to call functions is remarkably obvious. If you aren’t familiar with LISP dialects you will probably ignore the fact that you’re actually coding valid LISPs expressions to manage your server. You may ask your self: “But, it’s an API so I need to write my own Clojure code to use it, right?”. Writing your own code is actually optional because you can use the REPL (Read-Eval-Print Loop) to execute Clojure expressions. In a single line of code you can call any of the functions available. Look how we use the REPL to invoke a function that installs TomEE 1.7.1 Plus in the working directory.

clojure-repl-tomee-cli

The REPL gives a real feeling of an interactive shell. That’s why we didn’t wait too long to release TomEE-CLI. It’s a basic, but valid user interface that people could start using immediately. Features like auto-complete, history and multi-line commands are also provided by the REPL. In the long run, the REPL won’t be the only way to interact with TomEE-CLI. We are planning to add a rich shell interface for experienced hackers, an in-line parameters interface for easy integration with automation tools such as Jenkins, and a web interface for beginners and remote administrators.

You can find installation instructions in the readme file and a complete list of functionalities in the project’s wiki.

You may be surprised I’m devoting time to a JavaEE initiative after leaving it behind. Well, software development is all about people. So, even when a specification sucks, people using it are still good people, thus I’m writing it for them. Besides that, I’m happy to write Clojure code to solve real world problems faced by JavaEE developers in a daily basis.

Daniel and I understand that we may not have many contributors because the actual Clojure source code looks weird for Java developers. That’s what I thought when I first looked at it. But I can tell you that I’m not that smart and I was able to grasp the language in less than a month. Now, I’m delivering new functionalities in a short period of time, preserving the same level of performance and robustness offered by the JVM. When I became a father I realized time is my most precious resource. I simply can’t waste it anymore.

DSC00410

Case Study: Migrating a Large Project from Ant to Maven

The truth is we had been under difficult times. We spent almost three months to migrate our build mechanism from Ant to Maven. That’s the minimum time you have to put in your schedule if you are planning to do the same in a large project. There are still some collateral effects of this migration that we are struggling to solve, but fortunately they are not so critical.

The Context

Just to contextualize a little, we have a full Java EE 6 system composed of 25 integrated applications and each application has an average of 3 modules (EJB, WEB, etc), reaching ~80 modules. We manage something close to 500K lines of Java code (JSs, CSSs, JSPs and JSFs files not included), according to our Sonar analysis. It takes between 15 to 20 minutes to build everything. It depends on the mood of the server.

The decision to go for Maven came as a precondition to start a large scale refactoring of the application, which, despite using the latest technology available (Java EE 6), has suffered from a mix of frameworks, design flaws and multiple architectures over the years. We are going towards a single architecture grounded on the Java EE specification in order to optimize dependencies, reduce the evolution cost in a middle/long-term perspective and run seamless in our Glassfish Application Server.

The Duty

The project structure is almost the same as it was with Ant, thanks to the flexibility provided by Maven. We have a super pom.xml file in the root folder, which basically declares all modules, plugins, additional repositories, and dependencies. The dependencies are declared in a dependency management (using the tag <dependencyManagement>). This way, all version numbers are declared in a single place. Besides the super pom.xml, we have a folder for each integrated application and inside each folder we have a application pom.xml and three other folders, one for each Java EE module (EAR, EJB, WEB). The application’s pom.xml inherits from the super pom and it basically declares the modules composing the application. Inside the module folders we have one more level of pom files. These pom files inherit from their respective application’s pom files and describe the particularities of their modules. In summary, we have three levels of pom files, from the system as a whole to the level of Java EE modules.

Example of structure similar to the one we are using.

For development purposes, we avoid deploying the entire application locally. That’s why we have an EAR module in each application. This way, we save time deploying only the application we are working on. Those application EAR modules are not taken into consideration when packaging to deploy on the servers. To build the full EAR for the servers we have a special application that contains a EAR module, whose pom file declares all EJB and WEB modules as dependencies. Performing the goal package on this pom.xml will actually create the super EAR file.

EAR module to package the entire system in a single deployment file.

The Good

Evaluating the project after Maven implementation, we could notice the following benefits:

Maven contributed to simplify the logic behind the build: Now, everybody is aware of what is going on because pom.xml files are much easier to understand than build.xml files. Our Ant files were generated by Netbeans, thus very big and unreadable. We were actually lucky to have them working for so long, since it was difficult to maintain them. No question that we would find a point of irremediable chaos very soon.

Maven also contributed to put some order in all project dependencies: We went from a ~100 MB EAR package to a ~50MB one, a very significant reduction of 50%. It contributed to make the deployment time shorter.

We had the opportunity to clean up the project: While gathering the dependencies to write the pom.xml files, we discovered that some modules were not needed any more; libraries spread through the modules were also removed in favour of Maven’s dependency management. In summary, we have said “Maven is a nightmare” until the day we finally had everything in order and we became happier and relaxed. That’s what most people say as well, since it’s not easy to find solutions for a particular scenario, and everybody has a particular scenario to deal with.

Short learning curve: Once Maven was put in place, we visited all developers, reconfigured Netbeans to recognize the Maven projects and explained to them how to proceed from that point on. All of them could immediately continue with their development activities and just a few call for support were triggered. None of these calls were blocking issues. I have to say that Netbeans contributed a lot to reduce the learning curve because all necessary goals are performed directly from the IDE and there is no need to go to the command line, as it usually happens with Eclipse.

The Bad

Unfortunately, we had some setbacks:

The build now takes longer with Maven: We have noticed a decline on developers’ productivity due to that, making us a bit frustrated at the end 🙁 Since we are not going to rollback to Ant, we are considering JRebel for dynamic reloading of changed code to compensate the additional time we are spending.

We are using some libraries that can’t be found in Maven’s central repositories or elsewhere: Some are commercial libraries and others are too old. We also found libraries available with inconsistencies, throwing many exceptions at runtime (i.e. Apache FOP). For each one of these situations we had to find workaround solutions that were not so elegant, but we cannot stay like that for so long. We have to install a local Nexus repository to address special cases. This is in our check-list.

Occurrence of unexpected behaviours: the best of the efforts is not enough to avoid unexpected behaviours in the application. We have built a spreadsheet listing all applications and their respective modules; documented all dependencies from libraries and between modules; depicted the project structure; went deeper into details. In order to elaborate this spreadsheet we spent several days investigating the guts of the system, absorbing low level mechanisms and design decisions. All the collected information was used on the migration. Nevertheless, the rearrangement of dependencies and the removal of duplicates and unused libraries caused broken navigation flows, alert messages coming from nowhere, changes on URL paths and many other surprises. Unfortunately, we couldn’t predict those problems and we spent much more time on fixes than what was initially foreseen.

The Conclusion

I would like to conclude giving some advices for those planning to adopt Maven in a middle/large scale project:

Communicate the migration to end-users: it’s very important to communicate to end-users what is going to happen in the coming days. Users should be aware that, as they have the duty to improve their business, we also have the duty to improve ours. It means the delivery of new features will temporarily slow down to pave the way to a better product with faster releases. If they are not aware of what is going on, they will have very low tolerance to problems, undermining the reputation of the project.

Don’t be afraid to change even what is working well: We have questioned ourselves why to migrate to Maven if Ant is working so well. Actually, our strategy is to reduce complexity to streamline the resolution of problems. So, we were not afraid to migrate because preventive measures are very important too.

Keep the entire migration under version control to help the investigation of problems: Once all pom files were created and versioned, every little changes in those files should be committed separately in order to revert changes in case of unexpected problems. It helps to isolate the causes. It is also good to know that there is no conflict between Ant and Maven files. So, both can stay in the same branch during the migration without any impact on developers.

Don’t start a big refactoring without a build system like Maven: a successful refactoring depends on a detailed understanding of the application and adopting Maven will push you to perform an extensive investigation. In addition to that, the project will be cleaner and better organized.

There are other alternatives to Maven, such as Apache Ivy and Gradle, but, despite all deserved criticism, we still recommend Maven when replacing Ant because of its maturity; vast plug-in portfolio; abundant documentation on the web; and rich IDE support. However, it’s a good idea to evaluate other alternatives once Maven is put in place. After the initial tsunami, other waves will come quietly.

JUG Management Now on Git

The JUG community asked and we have moved the JUG Management source code from SVN to Git. I have to admit that I’m new in Git and it seems to be a quite change of paradigm from SVN. My first feeling is that it is more complex. For the moment, my motivation to learn Git comes from the fact that there is a big probability that the market will value this knowledge.

To access the Java.net Git repository is not a trivial task 🙁 You will need SSH (Security Shell protocol) to have an encrypted connection to the server. I think this is too much for our needs, since this is not such a critical system, but this is real life, thus I followed the steps below:

  1. Download and install a Git client according to your operating system. Clients are available at http://git-scm.com/download.
  2. Installing Git is not enough to start working. You have to configure it, adding a public SSH key to your site profile as described in Generating an SSH Key. The whole process will take some time, but if you do it carefully, step by step, everything will work fine. It worked in my first attempt 😉
  3. register yourself in CEJUG’s project at java.net. You will have access to the repository only if you are a member of the project. Registering in the project doesn’t mean you will become a CEJUG member. Actually, we use JUG Management to control our members 😉
  4. When you login on Java.net and go to the source code section, you will be able to see the checkout URI of JUG Management’s repository. The address contains your username. Example: ssh://[user-name]@git.java.net/cejug~jug-management.
  5. Copy the URI above and go to the command line and type the following command to checkout the code: git clone ssh://[user-name]@git.java.net/cejug~jug-management. It will create a folder “cejug-jug-management” in the directory you ran the command and the full source code will be available there.

This is a good start. Now you can open the source code and try to learn the project. I will explore in the next post how to open the source code in an IDE and build a package for deployment. At the same time, I’m learning how configuration management works with Git in order to start receiving your contributions. I’m studying the book Version Control With Git by Jon Loeliger for this. I hope the idea of branch is still there, just with a different name.