Tag Archives: integration

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.

Integrating Jira with Netbeans

One of the advantages of hosting your open source project at Java.net is the availability of Jira to track your issues. Jira is one of the most popular issue tracking system available on the market, which drives tool developers to support it. This is the case of Netbeans, my working IDE, and also the case of Eclipse.

I recently configured my Netbeans to access Jug Manangement‘s issues. If you want to do the same, or with another project hosted on Java.net or even connect to the Jira available on your company’s Intranet, then the following instructions may help you.

The first step is to install Jira plugin on Netbeans. In the menu, select Tools and then Plugins. Go to the tab Available Plugins and select JIRA. Follow the installation procedure and restart the IDE at the end. The figure below shows the plugin already installed. You may check as well if JIRA is in your list of Installed plugins to make sure everything went well.

In the view Services, where we connect to databases, webservers and others, we also find a new kind of service called Issue Trackers. By clicking with the right button on this service, you are about to create a connection to a issue tracker. A dialog like the following figure appears. Give any name to your connection, since this is not a predefined value. In case of Java.net, use the URL https://java.net/jira and the credentials you use to authenticate in the portal. Click on Validate to make sure that you input the values correctly and the connection with the server is working. Click on Ok to finish.

Now, you are connected but not ready to work yet. The next step is to find the issues. For that, click with the right button on the issue tracker that you just created and select the option Find Issues. It opens a new tab in the editor area where you are able to build your query as you usually do using Jira on a web browser. When you build the best query for your needs you can save it to constantly work with that. In the following figure I built a query that shows me all open issues of the project jug-management.

You can do something similar to your project and control your issues directly from the IDE. One of the main benefits of this approach is that, by restricting the use of the browser, we reduce the probability of losing the focus on the work due to other entertainment activities on the web such as news, social networks, chatting and so on.

New CEJUG Open Source Project

As I have mentioned yesterday, I’m working on a new project, managed by the CEJUG community, which aims to develop a web application for managing Java User Groups. We put it into production in the first day of the decade, January 1st, 2011, and we made the source code freely available on our java.net project.

The first goal we want to achieve is the definition of what is actually being a CEJUG member. Nowadays, we simply consider all those registered in our technical mailing as members. This simplicity is good for management purposes, but we lose lots of information because of that. We don’t know, for instance, for what reasons a member is leaving the group. Did we do something wrong? What can we do to get better and get members back into the boat? We also noticed that even non-technical people, as entrepreneurs, recruiters, and those who decided to unsubscribe because of too many messages, would like to keep in touch with the group, not necessarily going into technical discussions, but proposing other ways to help. Adopting a separate application to manage subscriptions would help us to collect more feedback and be more inclusive.

Developing our own solution can make data work in our favour and allow our sustained growth. Consequently, we are generating an additional source of knowledge for the community. This application is open source and everyone can run and see how CEJUG works. Beginners will have a solid source to start their studies on the development of Java web applications, experts can help with bug fixing, refactoring, and developing new features according to our issue tracking. Adopted design patterns may be subject of valuable and warming discussions in our community.

Of course the application was developed in Java 😉 We have the duty to write the software architecture document in the coming days, but we can already say in advance what we are using to develop and deploy the application. The presentation layer was developed in JSF 2.0, using the Primefaces component library; the business layer was implemented in EJB 3.1; the persistence layer was implemented in JPA 2.0; data is persisted in MySQL; and everything is running on Glassfish 3.0.1 Application Server. The current version was developed using Netbeans 6.9 due to its productivity when developing JEE applications. We rely on the container to manage security, database transactions, connection pools, and email sessions.

The next step is to document the application, add customisable features and internationalise it in order to spread its adoption by several other JUGs out there. We are looking for contributors and supporters to make this a successful open source project. We hope one day, we could promote interoperability between JUGs through this application, sharing mutual knowledge, events, effort on the growth of the Java platform and the Java community.

Yet Another System for Multimedia Information Management – YASMIM

As part of my research, I’m developing a system for media archiving with features that makes it a media information management. I figured out a nice acronym for this system: Yet Another System for Multimedia Information Management – YASMIM. The reason why it is “Yet Another System” is because there are several multimedia archiving systems out there and I’m going to create one more (I’m so brave! :P). It is not just a multimedia archiving system, but also a system to organize all information possibly related to the content of the media.

This system has 3 personal goals:

  1. demonstrate my scientific contributions to the field of multimedia systems;
  2. update my expertise on enterprise systems and manipulation of large datasets to get ready to the market again; and
  3. share my acquired knowledge with people interested in JEE6 (EJB3, JPA, JSF) server applications and JavaFX desktop applications because the best way to learn is sharing and teaching.

According to my plans, I’m going to finish my PhD in October, 2010. I’m writing the thesis right now and it is all about the YASMIM system. it’s planned to support several kinds of media, including images, videos, audios, and 3D models. The main differentials are the possibility to segment and annotate all these kinds of media within only one integrated system and provide these features through a web service interface, in addition to the conventional web interface. This system is open source, but I can only make it fully available after my thesis defense. However, I have published an initial (but compilable) source on GitHub. If you wish, you can help me to develop it and we can figure out together many other innovative aspects. 😉

Why did I chose JEE6 and JavaFX? The first reason is that I’m supposed to get into the market soon and I have to update my knowledge of enterprise systems, which was what I used to work before the PhD. But of course, I cannot put in the thesis this reason. Better to find reasonable technical reasons. So, the technical reasons to choose JEE6 were:

  • the architecture allows the expansion of available resources without redesigning the code;
  • support for multiple user sessions;
  • support for authentication and authorization and I just have to worry about the content sensitiveness;
  • totally based on POJO, so I can keep the code as simple as possible while focusing on the algorithm part; and
  • the support for web services is native and implemented by Java annotations.

The technical reasons to choose JavaFX as the client technology were:

  • vectorial user interface rendering;
  • multi-platform, including mobile devices; and
  • good support for media playback.

An alternative platform to implement this system would be Adobe Flash. However, a basic technical problem prevented me to choose this platform: I use a Linux 64 bits operating system and it doesn’t work appropriately on it. Thus, besides having a bigger number of machines supporting Flash, some platforms do not support it well. Considering JavaFX, most platforms support it well, however, less machines have it installed. So, my decision was in favor of more compatibility.

If you are interested in this kind of application, not only for multimedia processing, but also to learn about Enterprise Java and JavaFX, be my guest and get involved on http://github.com/htmfilho/Yasmim.

Jersey and JSF Conflict caused by Netbeans

Have you noticed that JSF 2.0 has a new pre-defined directory called “resources” that is located in the web content? According to JavaServer Faces 2.0, The Complete Reference, “files in this directory are treated specially by the JSF Runtime. (…) files and directories within the /resources directory are intended to be included in other pages in the application. Content here can be images, stylesheets, and composite components.“. Therefore, if your Java web application has a /resources directory with a different meaning, then you have to consider renaming it to avoid conflicts when migrating to JSF 2.0.

But there are more conflicts to deal with. I was having some relaxing time programing my JSF 2.0 application (Yasmim) on Saturday night when I decided to implement some RESTful web services. Knowing that Netbeans is like a Swiss army knife when developing JEE applications, I went into its special features to support the JAX-RS specification (JSR 311) and I could get most of the necessary configuration done automatically. However, this automation causes a conflict with the JSF application if you don’t pay attention to a simple detail shown in the figure below.

The field “REST Resources Path” has the default value “/resources”. This path is used in the application URL to denote the invocation of RESTful web services. For instance, in the URL “http://localhost:8080/yasmim/resources” anything after “/resources” is considered as a RESTful web service. If something after “/resources” is not correctly mapped, then a HTTP error occurs. This is actually a good practice because the key abstraction of information and data in REST is a resource. Representing it in the URL makes it clear.

However, when the application also uses the JSF 2.0 framework, this REST resource path conflicts with the JSF resources directory. As a consequence, files in the resources directory obviously are not mapped as services and won’t be available for JSF pages. In practice, CSS and script files become unavailable, destroying the design and layout of the website.

To solve this conflict, we have to change the proposed resource path to another value. In my case, I’m using “/service”, which is still coherent because REST is a style of web service implementation. After changing this value you have to clean and rebuild the project and redeploy the application because hot deployment in Glassfish doesn’t work in this case.