Archive | March 2013

Executing JavaScript on a Java VM

These days I stumbled upon an interesting feature of the Java Virtual Machine. Since version 1.6 you can request from your Java code a ScriptEngineManager. This factory allows you to request an execution engine for JavaScript, which can be used to execute arbitrary JavaScript code within your Java program.

The following snippet demonstrates how to execute a string containing JavaScript code:

ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
if (engine != null) {
  try {
    engine.eval(script);
  } catch (ScriptException e) {
    throw new JsExecutionException(e);
  }
} else {
  throw new JsExecutionException("No JavaScript engine available.");
}

To try this JVM feature out, I implemented a small java application that executes a JavaScript given as command line parameter. You can find the sources on github: https://github.com/siom79/js-executor.git.

Advertisements

Move all files in the current directory to an archive folder via batch script

Sometimes you work on some files within a directory and want to do a backup from time to time. Of course, if you have a version control system like git or svn by hand, you might use this. But if you have no versioning tool, a simple technique often used is to copy all files to an archive folder in the current directory and append a version string to the filename. If you do this a few times after another, you might want to write a small batch script, that does this stupid job for you.

Today I found myself in this situation, thus I started writing a small batch script that copies all files except the batch file itself to the an archiv folder, appending a timestamp to the filename:


set archivefoldername=Archiv

set hour=%time:~0,2%
if "%hour:~0,1%" == " " set hour=0%hour:~1,1%
echo hour=%hour%
set min=%time:~3,2%
if "%min:~0,1%" == " " set min=0%min:~1,1%
echo min=%min%
set secs=%time:~6,2%
if "%secs:~0,1%" == " " set secs=0%secs:~1,1%
echo secs=%secs%

set year=%date:~-4%
echo year=%year%
set month=%date:~3,2%
if "%month:~0,1%" == " " set month=0%month:~1,1%
echo month=%month%
set day=%date:~0,2%
if "%day:~0,1%" == " " set day=0%day:~1,1%
echo day=%day%
set datetimef=%year%-%month%-%day%_%hour%%min%%secs%

if not exist %archivefoldername% mkdir %archivefoldername%

for %%i in (*) do (
 if not %~n0 == %%~ni (
  copy %%i %archivefoldername%\%%~ni_%datetimef%%%~xi
 )
)

Apache ActiveMQ and Tomcat

Today I want to investigate how to integrate JMS functionality into a web application running within a Tomcat servlet container (7.x). As we do not use a fully fledged application server, we have to care about registering the ConnectionFactory and Queue within the JNDI context. In this exmple I chose Apache ActiveMQ as a JMS provider. As a simple example, I want to have two Servlets: The first Servlet pushes messages into a queue, whereas the second Servlet pulls them out of the queue and displays the messages as an HTML page.

Let’s add the necessary maven dependencies to our pom.xml:

		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-core</artifactId>
			<version>5.7.0</version>
		</dependency>
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-web-api</artifactId>
			<version>6.0</version>
			<scope>provided</scope>
		</dependency>

As Tomcat has only a static JNDI, we add the ConnectionFactory and the Queue via the context.xml:

<?xml version='1.0' encoding='utf-8'?>
<Context>
    <Resource
            name="jms/ConnectionFactory"
            auth="Container"
            type="org.apache.activemq.ActiveMQConnectionFactory"
            description="JMS Connection Factory"
            factory="org.apache.activemq.jndi.JNDIReferenceFactory"
            brokerURL="vm://localhost"
            brokerName="LocalActiveMQBroker"
            useEmbeddedBroker="true"/>

    <Resource name="jms/queue/MyQueue"
              auth="Container"
              type="org.apache.activemq.command.ActiveMQQueue"
              factory="org.apache.activemq.jndi.JNDIReferenceFactory"
              physicalName="MY.TEST.FOO.QUEUE"/>
</Context>

Let’s setup a simple Servlet that listens to the URL /sendMessage:

@WebServlet(name = "SendMessageServlet", urlPatterns = "/sendMessage")
public class SendMessageServlet extends HttpServlet {

    private static final Logger logger = LoggerFactory.getLogger(SendMessageServlet.class);

    @Override
    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
    	logger.info("doGet() called");
    	String parameter = getTextParameter(httpServletRequest);
        sendMessage(parameter);
        writeResponse(httpServletResponse, parameter);
    }

[...]

}

The text to send is given as a GET-Parameter to the URL. The method sendMessage() contains the relevant code. Here we can access the ConnectionFactory through our JNDI Context:

            InitialContext initCtx = new InitialContext();
            ConnectionFactory connectionFactory = (ConnectionFactory) initCtx.lookup("java:comp/env/jms/ConnectionFactory");
            Connection connection = connectionFactory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer((Destination) initCtx.lookup("java:comp/env/jms/queue/MyQueue"));

Thus, sending a text message to the queue is quite simple:

            TextMessage testMessage = session.createTextMessage();
            testMessage.setText(text);
            testMessage.setStringProperty("aKey", "someRandomTestValue");
            producer.send(testMessage);

Now it is time to setup a second Servlet that enables us to read all messages from the queue. The code for the sceleton is quite similar to the first Servlet:

@WebServlet(name = "ReceiveMessageServlet", urlPatterns = "/receiveMessage")
public class ReceiveMessageServlet extends HttpServlet {

	private static final Logger logger = LoggerFactory.getLogger(ReceiveMessageServlet.class);

	@Override
	protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
			throws ServletException, IOException {
		logger.info("doGet() called");
		Optional<String> text = receiveMessages();
		writeRepsonse(httpServletResponse, text);
	}

[...]
}

In our receiving Servlet we use the following code to create a QueueReceiver:

InitialContext initCtx = new InitialContext();
QueueConnectionFactory connectionFactory = (QueueConnectionFactory) initCtx.lookup("java:comp/env/jms/ConnectionFactory");
QueueConnection queueConnection = connectionFactory.createQueueConnection();
QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) initCtx.lookup("java:comp/env/jms/queue/MyQueue");
QueueReceiver receiver = queueSession.createReceiver(queue);

Finally, we can receive the text message, we have sent before:

queueConnection.start();
try {
	Message m = receiver.receive(1000);
	if (m != null && m instanceof TextMessage) {
		TextMessage tm = (TextMessage) m;
		text = Optional.of(tm.getText());
		logger.debug(String.format("Received TextMessage with text '%s'.", text));
	} else {
		logger.debug(String.format("No TextMessage received: '%s'", m));
	}
} finally {
	queueSession.close();
	queueConnection.close();
}

The whole source code can be found on github: https://github.com/siom79/jms-and-tomcat.