Saturday, June 25, 2011

Executable WAR

Recently I created very small and lightweight web application. It supposed to be using web sockets, so I decided to use Jetty as application server, but instead of using it like container, I decided to save on project and configuration folders and scripts and deploy it as executable WAR.
It was surprisingly easy to do. Basically, only thing that is needed is maven with Shade plugin. This plugin allows to pack all dependencies together in single JAR. Also it allows to modify manifest, and comes with simple examples.
So, all you need to do is to add jetty dependencies to pom.xml, for example:

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>8.0.0.M2</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-jndi</artifactId>
            <version>8.0.0.M2</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-plus</artifactId>
            <version>8.0.0.M2</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-start</artifactId>
            <version>8.0.0.M2</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>8.0.0.M2</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>8.0.0.M2</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>8.0.0.M2</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-jmx</artifactId>
            <version>8.0.0.M2</version>
        </dependency>

        <dependency>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jsp-2.1-glassfish</artifactId>
            <version>2.1.v20100127</version>
        </dependency>

And Shade plugin configuration:

            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-shade-plugin</artifactId>
              <version>1.4</version>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>shade</goal>
                </goals>
                <configuration>
                  <artifactSet>
                    <includes>
                      <include>org.eclipse.jetty:*</include>
                      <include>org.mortbay.jetty:*</include>
                      <include>net.sourceforge.jtds:jtds</include>
                      <include>org.slf4j:*</include>
                      <include>log4j:*</include>
                      <include>c3p0:c3p0</include>
                    </includes>
                  </artifactSet>
                  <transformers>
                    <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                      <manifestEntries>
                        <Main-Class>org.eclipse.jetty.start.Main</Main-Class>
                        <Build-Number>123</Build-Number>
                      </manifestEntries>
                    </transformer>
                  </transformers>
                </configuration>
              </execution>
            </executions>
            </plugin>


And as output you should get nice, executable WAR web application, that is ready to be launched as easy as:

java -jar myexecutable.war jetty.xml

Of course it is good idea to externalize logging or jetty configuration in separate jetty.xml file, so you can change it without creating new deployment.
It can be as simple as:

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure id="FileServer" class="org.eclipse.jetty.server.Server">

    <Call name="addConnector">
      <Arg>
          <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
            <Set name="port">8080</Set>
            <Set name="Host">localhost</Set>
          </New>
      </Arg>
    </Call>

    <Set name="handler">
      <New class="org.eclipse.jetty.server.handler.HandlerList">
        <Set name="handlers">
          <Array type="org.eclipse.jetty.server.Handler">
            <Item>
              <New class="org.eclipse.jetty.webapp.WebAppContext">
                <Set name="contextPath">/myexecutable</Set>
                <Set name="war">myexecutable.war</Set>
              </New>
            </Item>
          </Array>
        </Set>
      </New>
    </Set>

  <New id="onewalletDS" class="org.eclipse.jetty.plus.jndi.Resource">
    <Arg>myDS</Arg>
    <Arg>
      <New class="com.mchange.v2.c3p0.ComboPooledDataSource">
         <Set name="driverClass">net.sourceforge.jtds.jdbcx.JtdsDataSource</Set>
         <Set name="user">user</Set>
         <Set name="password">password</Set>
         <Set name="jdbcUrl">jdbc:jtds:sqlserver://localhost/myds</Set>
     </New>
    </Arg>
  </New>

</Configure>

Friday, April 1, 2011

Playing music file from HTML page

This is first time I need this in many years, but finally this day has come: I need to play MP3 file from web page.
Looks like the easiest way to do is by using embed tag, so when I need it is needed to play it, I just call from javascript:
$('#sound_element').html("<embed src='scripts/"+file+".mp3' hidden='true' autostart='true' loop='false'>");
Of course I need to have this div somewhere on the page:
<div id="sound_element"></div>
And it does the magic. I found that it plays flawlessly in Chrome, but for Firefox it asks for Quicktime plugin. But I need it for managed environment, so it is not a big deal.
Finally, I can add some tunes to my blog! ;)

Skip XML declaration in JAXB

By default JAXB outputs XML declaration when you marshal your objects:
For example, this:

JAXBContext context = JAXBContext.newInstance(Command.class, Message.class...);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(command, writer);
will output this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<message channel="test"/>


If you don't need to use XML declaration in your JAXB output, it is easy to skip it by setting property "jaxb.fragment" to true. So, this:
JAXBContext context = JAXBContext.newInstance(Command.class, Message.class...);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty("jaxb.fragment", Boolean.TRUE);
marshaller.marshal(command, writer);
will output only this:
<message channel="test"/>


Friday, March 18, 2011

Get text from java mail

If you don't want to dig javamail structures and mime types, there is easy way to extract text from Message object described in javamail official docs (I wonder why they didn't put it directly into specification).

Friday, February 25, 2011

Spring Integration namespaces in resources.groovy

Spring Integration relies heavily on namespaces usage, so if you need to use it, this can be easily defined in Grails Spring DSL:


beans = {
  xmlns integration:"http://www.springframework.org/schema/integration"
  xmlns mail:"http://www.springframework.org/schema/integration/mail"
  xmlns jms:"http://www.springframework.org/schema/integration/jms"

}

After that you can define your channels like:

  integration.channel(id:'inboundEmailChannel')

Thursday, February 24, 2011

Processing incoming emails with Spring Integration

Recently, I had a task to automatically process emails that come to specified address. Trivial solution is to create some periodic task with Quartz or Timer and pull new emails and process them. I googled if there is ready lib to do this and found that this can be done with Spring; or more specifically with Spring Integration. I heard about this project, but didn't payed a lot of attention to it. Main idea behind it is - this is small local ESB, so basically if you need to act on some incoming event or send some outgoing event to some system, this is nice place to look at. Another good thing is that it provides easy and out-of-the-box ready interface to many different systems, which is exactly what I was looking for email processing.
So with Spring Integration, reading email is just few beans definition (in Grails Spring DSL):


  integration.channel(id:'inboundEmailChannel')

  mail.'inbound-channel-adapter'(id:"imapAdapter",
      'store-uri':"imaps://${CH.config.logging.imap.credentials}@imap.gmail.com/INBOX",
      'java-mail-properties':['mail.imap.socketFactory.class':'javax.net.ssl.SSLSocketFactory',
            'mail.imap.socketFactory.fallback':false,
             'mail.store.protocol':'imaps', 'mail.debug':false],
      channel:"inboundEmailChannel",
      'should-delete-messages':true,
      'should-mark-messages-as-read':true,
      'auto-startup':true) {
          integration.poller('max-messages-per-poll':"1", 'fixed-rate':"5000")
   }

   integration.'service-activator'( 'input-channel':"inboundEmailChannel",
                ref:"emailService", method:"inboundEmail")


So, with this, when you have incoming email, it will call inboundEmail method of emailService.

Tuesday, January 11, 2011

Configuration properties in resources.groovy

In Grails there is support for property placeholders in resources.xml, but for resources.groovy you should do it manually. Fortunately, it is quite easy, here is example:

import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH

beans = {
  integration.channel(id:'channel', host:'imaps://user:${CH.config.imap.password}@imap.gmail.com/INBOX')
}