Category Archives: Articles

Welcome to my RPi: simple JavaEE exercise with webservice and JMS

So my Raspberry Pi has arrived and I was eager to try out some Java programming on it; actually, I wanted to have a first simple exercise to stress test it with a JavaEE container, which I choose JBoss AS 7. Of course the overall performances are nothing comparable to usual servers where you would normally deploy a JavaEE application, however being for small/home projects it doesn’t seems too bad either in order to get started!

Photo 16-12-12 20 24 38

The goal for this exercise is simple: develop a webservice to be exposed in a JavaEE application, which “spool” the content of the webservice call onto a JMS Queue.

Listed:

  • Rasberry Pi (model B)
  • Java 7 SE for Embedded
  • JBoss AS 7 as the JavaEE container
  • Apache Camel
  • SoapUI to test the webservice
  • Hermes JMS as a consolle to access the JMS Queue

First things first, in order to install the Java SE 7 RE, I overall followed the instructions found here, and also a maybe plain but still interesting video on YouTube of what seems to be a Java User Group session – check out the related James Gosling video as well, it’s not RPi related but a very interesting talk nevertheless from THAT James Gosling!

Anyway, once the JRE is installed on the RPi:
JRE on the RPi

… it’s time to install JBoss AS 7:
Screen Shot 2012-12-16 at 10.49.27

In this case, what I did is a custom standalone.xml configuration file to have all the basics, plus JMS which HornetQ is the implementation for JBoss AS.

Time to code!

With the JBoss Developer Studio IDE (basically Eclipse IDE + JBoss Tools), Maven for a simple webapp, and switch Java Compiler to 1.6:

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>

and some simple dependencies:

		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-core</artifactId>
			<version>2.10.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-jms</artifactId>
			<version>2.10.3</version>
		</dependency>

		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-api</artifactId>
			<version>6.0</version>
			<scope>provided</scope>
		</dependency>

The former block is to have Apache Camel to simplify as much as possible, while keeping loosely coupled, the integration between the webservice and the JMS, while the latter block is for the JavaEE libraries provided by the JBoss AS container.

Then, time to code the webservice:

@WebService()
public class SpoolOnQueue {

	@EJB
	CamelBootstrap cb;

	@WebMethod()
	public String sayHello(String name) {
	    cb.getProducerTemplate().sendBody("direct:spoolOnJms", name);
	    return "Your message has been spooled on JMS";
	}
}

Which is actually rather simple: it defines a webservice class thanks to the @WebService and related @WebMethod annotation, for a sayHello() method of our interest, in charge of spooling the content of the message onto the JMS queue via the Camel’s sendBody() to a specific route.

There is a CamelBoostrap cb dependency injection, which is the JavaEE component in charge of managing the Camel context and routing, defined as:

@Singleton
@Startup
public class CamelBootstrap {
	private CamelContext camelContext;
	private ProducerTemplate producerTemplate;

	public CamelContext getCamelContext() {
		return camelContext;
	}

	public ProducerTemplate getProducerTemplate() {
		return producerTemplate;
	}

	@PostConstruct
	protected void init() throws Exception {
		camelContext = new DefaultCamelContext();
		camelContext.addRoutes(new RouteBuilder() {
			@Override
			public void configure() throws Exception {
				// in the JMS connection we can use # for the ConnectionFactory because by not using Spring the default for Camel is the JNDIRegistry
				// just remind by default it's implied it's a Queue as per Camel JMS doc
				from("direct:spoolOnJms")
				.log("spoolOnJms: ${body}")
				.to("jms:sample?connectionFactory=#ConnectionFactory");
			}
		});
		camelContext.start();
		producerTemplate = camelContext.createProducerTemplate();
	}
}

The CamelBoostrap therefore is a simple Startup, Singleton JavaEE Bean, in charge of initializing the CamelContext, the Camel’s ProducerTemplate, and the one and only camel route of our interest here:

  • starting at direct:spoolOnJms
  • logging the body content
  • and spooling the body content onto the jms:sample JMS Queue

Time to amend the web.xml configuration file to the 3.0 Servlet specs (meaning as well EJB 3 in this case) and linking the aforementioned SpoolOnQueue webservice class:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <display-name>SpoolOnQueue</display-name>
    <servlet-name>SpoolOnQueue</servlet-name>
    <servlet-class>net.tarilabs.test.SpoolOnQueue</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpoolOnQueue</servlet-name>
    <url-pattern>/SpoolOnQueue</url-pattern>
  </servlet-mapping>
</web-app>

Last thing before packaging up and deploy, is to define the JMS Queue, which in the camel route is defined as “sample”; to do so, there are several ways from JBoss consolle, to JBoss CLI, configuration files, etc. and in this case I opted for a deployable configuration file – in the WEB-INF/ directory it’s enough to place a HornetQ configuration file which must be ending with -jms.xml, et voilà!:

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

Note to self: in this case the -jms.xml HornetQ configuration file is to be placed in the WEB-INF/ directory because the application is packaged as a WAR, otherwise it should have been placed in the usual META-INF/ directory.

Time to deploy:
Screen Shot 2012-12-16 at 20.35.48

You may want to note the deployment takes longer if compared with today’s server or machine where you normally test and deploy these artifacts, however it’s not so bad for home project just reminds me the performance of my old Pentium II with JBoss 3 (or 5? can’t remember) with the difference that nowadays JavaEE 6 and JBoss AS 7 simplify and improve things by great extent.

Then, I use SoapUI to consume the SpoolOnQueue webservice with a call for a simple “Ciao here is some content to place on JMS. Matteo.” message:
Screen Shot 2012-12-16 at 20.37.47

In the JBoss log there is a line now for the Camel route started and spooling the body content on the JMS Queue.

Then, time to connect HermesJMS to this remote HornetQ / JBoss AS, as I hope to have contributed here:

When I start I can see the AS7 I can see in the log the RemoteConnectionFactory JNDI, but this cannot be seen in the console:9990 because of some bugs. However still:
12:47:16,653 INFO [org.jboss.as.messaging] (pool-4-thread-2) JBAS011601: Bound messaging object to jndi name java:jboss/exported/jms/RemoteConnectionFactory. With reference to the aforementioned -jms.xml HornetQ configuration file, from a REMOTE perspective: the RemoteConnectionFactory is on java:jboss/exported/jms/RemoteConnectionFactory, the Queue is on java:jboss/exported/jms/queue/sample

Therefore to configure HermesJMS

Step 1: Create a classpath group for HornetQ in HermesJMS
Only one JAR is needed, is the jboss-client.jar inside the directory bin\client of the JBoss AS 7 / JBoss EAP 6 directory

Step 2: Configure a HornetQ session in HermesJMS:
Class: hermes.JNDIContextFactory
Loader: HornetQ – the one defined in step #1
Properties:
binding=jms/RemoteConnectionFactory
initialContextFactory=org.jboss.naming.remote.client.InitialContextFactory
providerURL=remote://localhost:4447
securityPrincipal=MYUSERNAME
securityCredentials=MYPASSWORD
urlPkgPrefixes=org.jboss.naming.remote.client

Step 3: In the Destionations of the HornetQ session which you are defining as part of step#2, Add a new Desitionation
Name: jms/queue/sample
Domain: QUEUE

Now in HermesJMS in the left tree structure you have your Sessions > Your Session > Queue which you can double-click to connect to. You want to notice that for the binding you set the RemoteConnectionFactory without the java:jboss/exported prefix, and the same goes for the Queue defined, where from java:jboss/exported/jms/queue/sample I stripped away the java:jboss/exported prefix. Also notice that you can define the username/password either via the (securityPrincipal,securityCredentials) properties as above, or either use the “Connection” settings fields (User, Password) at the bottom of the Session Preference page of step#2.

So because the webservice has been consumed, which in turn started the Camel route, to spool on the JMS Queue:
Screen Shot 2012-12-16 at 20.38.12

The message now appears on the “sample” JMS Queue which is now inspected thanks to the HermesJMS consolle application.

Why do I blog this

I wanted to have a first “stress” test exercise with my new Raspberry Pi, not only to develop with some Java on it, but using a recent JavaEE container: the performances are not the best, still requires time to deploy or to compile .jsp pages (more in following posts) however I do believe for small/home projects the Rapsberry Pi is a very interesting, cheap both in terms of money and power consumptions, and cool platform where to deploy simple JavaEE applications!
ps: code available on github.

Advertisements

How to: news stand, kiosk, information display, news totem – part 2/2: Cycle PPT presentations from a recursive batch file

To quickly complement my previous entry, here is how I solved the problem of having the computer to Cycle between the PowerPoint slideshows. I found an easy way of using the CLI switches for the PowerPoint exe file, which you can either Google about or use this link provided for the ease referring to the 2007 version.

Therefore, you could for instance have a batch file loop.bat containing, for each PowerPoint presentation to be displayed, an invocation of the PowerPoint executable with the desired switches. As the PowerPoint presentation in my case are in a well-known directory location on the computer file system, I created a generateloop.bat file in order to construct the former loop.bat file programmatically.

In short, at the start-up of the computer, you call generateloop.bat because you want to:

  1. For each .ppt or .pptx file found that you want to display, write an entry in the loop.bat file, in order to launch PowerPoint and display as a slideshow that .ppt .
  2. Have the loop.bat file to call itself after it has cycled all the powerpoint entries
  3. As your last action of generateloop.bat, you want to start “loop.bat”

As I believe in this case is just easier to experiment with it rather than trying to explain it via words, here is a provided gist on github documenting the generateloop.bat batch file.

It is just a pity the PowerPoint Viewer seems to be missing the option to disable the “End with black slide” which instead you can find on the actual Office installation, otherwise rather than having to install Office on all these computer would have been fairly easier to deploy the simpler Viewer instead.

I really wonder if anybody has been more successful in using the Viewer on a kiosk installation where the requirement is to cycle between several PowerPoint presentations, instead than just one.

Mobile in the enterprise changes everything

An interesting article I originally read at the beginning of this year, and lately found again a printout – still so very true, I think mobile in the enterprise is still yet to start…

Mobile in the enterprise changes everything: In the medium-term a mobile strategy means thinking completely differently about the user experience.

In the world of mobile, IT leaders and business stakeholders must consider how new capability such as geolocation, sensors, near field communications, cameras, voice, and touch can be integrated into functionality. It also means that core issues such as security, device form-factor, and limited screen real-estate must be addressed.