Calculating Your Level of Naughtiness

To motivate his students, a computer science teacher of the Federal University of Ceará has challenged his class to develop an algorithm to calculate how naughty you are based on your birth date. The challenge is very silly, but it became a Brazilian hit.

The teacher said his original intention was to teach students to call functions from other functions, which is as much silly as the goal of the challenge, but no doubt that the idea is pretty effective on motivating young students.

safadao_questao_materia

The problem consists on writing a function that calculates the percentage of naughtiness and the remaining level of innocence of a person based on his/er birth date. The formula to calculate the level of naughtiness is:

naughtiness = incremental_sum(month) + (year / 100) * (50 - day)

where incremental_sum is a function that, given a number, calculates de sum of all numbers from 1 to the informed number included. The solution below is written in Clojure:

(defn inc-sum [num]
  (reduce + (range (inc num))))

(defn naughtness [day month year]
  (let [naughty (+ (* (- 50 day) (/ year 100.0)) (inc-sum month)) 
        angel (-  100 naughty)] 
    {:naughty naughty 
     :angel angel}))

(naughtness 10 9 78)
=> {:naughty 76.2, :angel 23.8}

The formula has absolutely no sense and doesn’t have any scientific foundation, but the result of the function is great fun to play with friends! Maybe the subject can push you to learn Clojure, doesn’t it?! 😉

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.

Installing Leiningen on Mac OS

leiningen-full

I’ve been playing with Clojure for quite sometime now. It’s a functional language hosted on the JVM, with a growing community and a very rich ecosystem. You can find libraries for every major problem, but in case you cannot find, you can count on the interoperability with Java will bridge the gap.

Nowadays, every programming language and platform offer a development environment with a build tool as foundation. Take as example Maven, Gradle and Sbt. It isn’t different in the Clojure world. It uses Leiningen as a build and project management tool. So, I would like to share with you how I’ve managed to install and configure Leiningen on my Mac.

First, create the directory /Applications/clojure to store Clojure’s related tools:

$ sudo mkdir /Applications/clojure

Navigate to the new directory, download the Leiningen script and give to the downloaded file permission to execute:

$ cd /Applications/clojure
$ sudo curl -O https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
$ sudo chmod +x lein

Add the new directory to the $PATH to be able to execute it everywhere in your system. To do that, navigate to the directory /etc/paths.d and use vi to create a file named clojure.lein with the content /Applications/clojure:

$ cd /etc/paths.d/
$ sudo vi clojure.lein

This change is not immediately taken into account. So, you will have to close the current terminal and open a new on. Execute the following command to check whether the $PATH variable was correctly modified to include Leiningen’s path:

echo $PATH

You should be able to find the path /Applications/clojure concatenated within the value.

Finally, execute the command lein for the first time to install Leiningen:

$ lein

It will download the latest version of Leiningen and make you ready to program in Clojure. Start the Clojure REPL with the following command:

$ lein repl

Have fun with Clojure and Leiningen!

Working With JMS on JBoss Web Profile

If you didn’t get in contact with messaging systems yet you better do it soon. This concept is a key element in the architecture of scalable applications. Before it was a product but now it’s pervasive even natively embedded in some programming languages.

Let me help you to use messaging in a JavaEE application server. The Java application code is portable between application servers. Unfortunately, each application server has its own way to configure a messaging system. Since I can’t cover all of them, I will concentrate on JBoss 7 or superior (JavaEE 6/7). JBoss uses a messaging system called HornetQ, an open source message-oriented middleware. It offers queues (point-to-point) and topics (publisher-subscriber). I’m covering only queues in this post. Queues and topics can be used within a JavaEE application or across several applications. It’s a kind of integration pattern, but sadly less popular than web services. Since I’m not dealing with integration, I will narrow even more this post to cover a queue accessible locally only.

metro-crowd

I recently had to use a queue to asynchronously generate large files. Users were waiting too much for a response from the server after requesting those large files. The problem became serious when multiple users were doing that request simultaneously. By using a queue, I was able to generate files asynchronously, so the users didn’t have to wait anymore, and in sequence, avoiding exponential use of memory and IO.

To put some pepper on the issue, we were using JBoss Web Profile and it doesn’t support messaging. We would need to migrate to JBoss Full Profile, but it would require us to migrate all development machines and all server environments, otherwise the deployment descriptor with the queue configuration would break the deployment everywhere. Also, migrating to the full profile would bring together several additional services – that we don’t need at all – just to consume more resources. So, I had to figure out how to make the messaging system work in the web profile.

The first idea that came to my mind was to simply identify the messaging configuration in the full profile (standalone-full.xml) and copy it to the web profile (standalone.xml). I started by adding the extension module:

<extensions>
...
<extension module="org.jboss.as.messaging"/>
...
</extensions>

and with it comes its respective rather long subsystem:

<subsystem xmlns="urn:jboss:domain:messaging:1.4">
  <hornetq-server>
    <persistence-enabled>true</persistence-enabled>
    <journal-type>NIO</journal-type>
    <journal-min-files>2</journal-min-files>
    <connectors>
      <netty-connector name="netty" socket-binding="messaging"/>
      <netty-connector name="netty-throughput" 
            socket-binding="messaging-throughput">
        <param key="batch-delay" value="50"/>
      </netty-connector>
      <in-vm-connector name="in-vm" server-id="0"/>
    </connectors>
    <acceptors>
      <netty-acceptor name="netty" socket-binding="messaging"/>
      <netty-acceptor name="netty-throughput"
            socket-binding="messaging-throughput">
        <param key="batch-delay" value="50"/>
        <param key="direct-deliver" value="false"/>
      </netty-acceptor>
      <in-vm-acceptor name="in-vm" server-id="0"/>
    </acceptors>
    <security-settings>
      <security-setting match="#">
        <permission type="send" roles="guest"/>
        <permission type="consume" roles="guest"/>
        <permission type="createNonDurableQueue" roles="guest"/>
        <permission type="deleteNonDurableQueue" roles="guest"/>
      </security-setting>
    </security-settings>
    <address-settings>
      <address-setting match="#">
        <dead-letter-address>jms.queue.DLQ</dead-letter-address>
        <expiry-address>jms.queue.ExpiryQueue</expiry-address>
        <redelivery-delay>0</redelivery-delay>
        <max-size-bytes>10485760</max-size-bytes>
        <page-size-bytes>2097152</page-size-bytes>
        <address-full-policy>PAGE</address-full-policy>
        <message-counter-history-day-limit>
            10
        </message-counter-history-day-limit>
      </address-setting>
    </address-settings>
    <jms-connection-factories>
      <connection-factory name="InVmConnectionFactory">
        <connectors>
          <connector-ref connector-name="in-vm"/>
        </connectors>
        <entries>
          <entry name="java:/ConnectionFactory"/>
        </entries>
      </connection-factory>
      <connection-factory name="RemoteConnectionFactory">
        <connectors>
          <connector-ref connector-name="netty"/>
        </connectors>
        <entries>
          <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
        </entries>
      </connection-factory>
      <pooled-connection-factory name="hornetq-ra">
        <transaction mode="xa"/>
        <connectors>
          <connector-ref connector-name="in-vm"/>
        </connectors>
        <entries>
          <entry name="java:/JmsXA"/>
        </entries>
      </pooled-connection-factory>
    </jms-connection-factories>
    <jms-destinations>
      <jms-queue name="ExpiryQueue">
        <entry name="java:/jms/queue/ExpiryQueue"/>
      </jms-queue>
      <jms-queue name="DLQ">
        <entry name="java:/jms/queue/DLQ"/>
      </jms-queue>
    </jms-destinations>
  </hornetq-server>
</subsystem>

No changes from the original. I just copied and pasted the entire messaging subsystem. Then I added a socket binding just in case I needed queues and topics for integration purposes later on:

<socket-binding-group
   name="standard-sockets"
   default-interface="public"
   port-offset="${jboss.socket.binding.port-offset:0}">
  ...
  <socket-binding name="messaging" port="5445"/>
  <socket-binding name="messaging-group"
     port="0"
     multicast-address="${jboss.messaging.group.address:231.7.7.7}"
     multicast-port="${jboss.messaging.group.port:9876}"/>
  <socket-binding name="messaging-throughput" port="5455"/>
  ...
</socket-binding-group>

Finally, I added a reference to the resource adapter, defined above, in the EJB subsystem, as follows:

<subsystem xmlns="urn:jboss:domain:ejb3:1.4">
  ...
  <mdb>
    <resource-adapter-ref
       resource-adapter-name="${ejb.resource-adapter-name:hornetq-ra}"/>
    <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
  </mdb>
  ...
</subsystem>

And it worked! Be aware you can simply use the full profile to make the messaging work. No need to do all this configuration. But keep in mind that the full profile is going to load additional things you don’t need at all, such as:

  • org.jboss.as.cmp: container-managed persistence, deprecated in favour of JPA.
  • org.jboss.as.jacorb: an implementation of CORBA.
  • org.jboss.as.jsr77: abstracts manageable aspects of the J2EE architecture to provide a model for implementing instrumentation and information access.

metro-queue

On the application side I did three things:

1 – add the deployment descriptor hornetq-jms.xml to the folder WEB-INF to automatically create a queue during the deployment process. The descriptor has the following content:

<?xml version="1.0" encoding="UTF-8"?>
<messaging-deployment xmlns="urn:jboss:messaging-deployment:1.0">
  <hornetq-server>
    <jms-destinations>
      <jms-queue name="FileGenerationQueue">
        <entry name="/queue/FileGeneration"/>
      </jms-queue>
    </jms-destinations>
  </hornetq-server>
</messaging-deployment>

2 – create a MDB (Message-Driven Bean) to listen to the queue and process the messages as they arrive. For example:

@MessageDriven(name="FileGenerationQueue", activationConfig = {
     @ActivationConfigProperty(propertyName = "destination",
                               propertyValue = "queue/FileGeneration"),
     @ActivationConfigProperty(propertyName = "destinationType",
                               propertyValue = "javax.jms.Queue"),
     @ActivationConfigProperty(propertyName = "acknowledgeMode",
                               propertyValue = "Auto-acknowledge")})
public class LargeFileGenerationBean implements javax.jms.MessageListener {
  @Override
  public void onMessage(Message message) {
    // Code that will process messages coming from the queue.
  }
}

3 – and modify a Request Scoped Managed Bean to send messages to the queue. For example:

@ManagedBean
@RequestScoped
public class MyManagedBean implements Serializable {

  @Resource(mappedName="java:/ConnectionFactory")
  private ConnectionFactory connectionFactory;

  @Resource(mappedName="java:/queue/FileGeneration")
  private Queue queue;

  // Serializable class encapsulating data criteria.
  private DataCriteria dc;

  public String sendMessageToQueue(String message) {
    try (Connection connection = connectionFactory.createConnection()) {
      Session session = conn.createSession(false,
      Session.AUTO_ACKNOWLEDGE);
      MessageProducer producer = session.createProducer(queue);
      conn.start();

      ObjectMessage message = session.createObjectMessage(dc);
      producer.send(message);
    } catch (JMSException e) {
      ...
    }
  }
}

Let me know if you have any issues, then we can find the solution and make it better.

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