xpj's knowledge base » Java http://www.xpj.cz/expee Just another blog. Wed, 03 Nov 2010 10:24:22 +0000 en hourly 1 Compressing content using a servlet filter http://www.xpj.cz/expee/2010/11/compressing-content-using-a-servlet-filter/ http://www.xpj.cz/expee/2010/11/compressing-content-using-a-servlet-filter/#comments Wed, 03 Nov 2010 10:24:22 +0000 xpj http://www.xpj.cz/expee/?p=55 Java

One year and little bit more I was gzipping Spring remoting requests and responses. Now is time to gzip web application :-)

The simplest solution is to use filter in your web.xml. I found implementation in ehcache called net.sf.ehcache.constructs.web.filter.GzipFilter :-)

<filter>
 <filter-name>gzip</filter-name>
 <filter-class>net.sf.ehcache.constructs.web.filter.GzipFilter</filter-class>
</filter>

<filter-mapping>
 <filter-name>gzip</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>
]]>
http://www.xpj.cz/expee/2010/11/compressing-content-using-a-servlet-filter/feed/ 0
Spring remoting with gzip compression http://www.xpj.cz/expee/2009/06/spring-remoting-with-gzip-compression/ http://www.xpj.cz/expee/2009/06/spring-remoting-with-gzip-compression/#comments Mon, 29 Jun 2009 14:48:49 +0000 xpj http://www.xpj.cz/expee/?p=50 Java

GZip compression is well known standard, used almost everywhere. Modern web servers are able to communicate with modern browsers and this communication can be automatically gzipped. But if you are unsure, if your communication is compressed, you can use your own.

With the Spring HTTP remoting it’s so easy as to implement extensions for existing classes.

package cz.xpj.expee.spring.remoting.httpinvoker;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor;

/**
 * Extension of {@link SimpleHttpInvokerRequestExecutor} for gzip compression
 * @author xpj
 */
public class GZIPSimpleHttpInvokerRequestExecutor extends SimpleHttpInvokerRequestExecutor {

 /**
 * @see org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor#decorateInputStream(java.io.InputStream)
 */
 @Override
 protected InputStream decorateInputStream(InputStream is) throws IOException {
 return new GZIPInputStream(is);
 }

 /**
 * @see org.springframework.remoting.httpinvoker.AbstractHttpInvokerRequestExecutor#decorateOutputStream(java.io.OutputStream)
 */
 @Override
 protected OutputStream decorateOutputStream(OutputStream os) throws IOException {
 return new GZIPOutputStream(os);
 }

}

And the other side of your communication…

package cz.xpj.expee.spring.remoting.httpinvoker;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;

/**
 * Extension of {@link HttpInvokerServiceExporter} for gzip compression
 * @author xpj
 */
public class GZIPHttpInvokerServiceExporter extends HttpInvokerServiceExporter {

 /**
 * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter#decorateInputStream(javax.servlet.http.HttpServletRequest, java.io.InputStream)
 */
 @Override
 protected InputStream decorateInputStream(HttpServletRequest request, InputStream inputStream) throws IOException {
new GZIPInputStream(inputStream);
}

/**
* @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter#decorateOutputStream(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.io.OutputStream)
*/
@Override
protected OutputStream decorateOutputStream(HttpServletRequest request, HttpServletResponse response, OutputStream outputStream) throws IOException {
return new GZIPOutputStream(outputStream);
}

}

I tested this communication on some artificial data, and the results were really nice :-)

Sended (List with # of longs) Without GZIP [bytes] With GZIP [bytes]
1000 20328 2741
2000 40328 5235
3000 60328 7852

I know, this is not so good example, but with different data (some entities etc.) we are still better than without compression :-)

]]>
http://www.xpj.cz/expee/2009/06/spring-remoting-with-gzip-compression/feed/ 0
How stop embedded ActiveMQ in Spring http://www.xpj.cz/expee/2009/06/how-stop-embedded-activemq-in-spring/ http://www.xpj.cz/expee/2009/06/how-stop-embedded-activemq-in-spring/#comments Tue, 09 Jun 2009 14:34:17 +0000 xpj http://www.xpj.cz/expee/?p=38 Java

Today I ran into problems with embedded ActiveMQ broker in Spring Framework. The goal is to run local application, which uses Spring context to start AMQ and after this application is finished, AMQ should stop.

My setup of spring context xml is following (I’m using the amq schema and this is only the needed part).

<amq:broker id="broker" useJmx="false" persistent="false" start="true"  >
  <amq:transportConnectors>
    <amq:transportConnector uri="tcp://localhost:0" />
  </amq:transportConnectors>
</amq:broker>
<amq:connectionFactory id="connectionFactory" brokerURL="vm://localhost"/>
<amq:queue id="replyQueue" physicalName="replyQueue" />
<amq:queue id="requestQueue" physicalName="requestQueue" />

And the app looks like this:

context = new ClassPathXmlApplicationContext("client-local-context.xml");

 ComputingStarterService computingStarterService = (ComputingService)context.getBean("computingStarterService");
 computingStarterService.start("Test");

And the problem is, that the main part of application stops, but the AMQ is still running. I tried a lot of things and the only working thing is to use

context.close();

I don’t know if there is another way to stop embedded AMQ. How it works eg. in JUnit tests?

]]>
http://www.xpj.cz/expee/2009/06/how-stop-embedded-activemq-in-spring/feed/ 0
JTable with fixed columns http://www.xpj.cz/expee/2009/06/jtable-with-fixed-columns/ http://www.xpj.cz/expee/2009/06/jtable-with-fixed-columns/#comments Fri, 05 Jun 2009 12:18:23 +0000 xpj http://www.xpj.cz/expee/?p=34 Another solution

JTable with fixed columns is really problem. There is no “one-and-the-only-right” solution for fixing one or two columns while leaving others scrollable.

There are two solutions for this problem.

Two tables solution

This solution uses two tables, one for fixed columns and other for the rest. This solution is described in nice article Fixed Column Table and the same solution is used in JXTable from xframe project.

This solution works nice, but there is one small UI (maybe more visual) problem. Scrollbar is visible only on the part of table, which is scrollable.

Two tables solution

Two tables solution

Another solution

“Another” solution is described in Freezable JTables (are they extreme?). This solution uses custom component, which is exactly the same size like the fixed columns and the fixed columns are painted into this component. And everything looks like the JTable supports fixed columns.

The problem with this solution is, that the fixed columns are “image” :-) You can find some difficulties when you moved with scrollbar and tried to doubleclick on some cell in the fixed column. You will edit another cell, hidden under this “image” :-)

Another solution

Another solution

I will continue with searching :-)

]]>
http://www.xpj.cz/expee/2009/06/jtable-with-fixed-columns/feed/ 0
Difference between jee:jndi-lookup and JndiObjectFactoryBean? http://www.xpj.cz/expee/2009/06/difference-between-jeejndi-lookup-and-jndiobjectfactorybean/ http://www.xpj.cz/expee/2009/06/difference-between-jeejndi-lookup-and-jndiobjectfactorybean/#comments Thu, 04 Jun 2009 12:18:02 +0000 xpj http://www.xpj.cz/expee/?p=25 Java

I found slight difference between usage of <jee:jndi-lookup and definition of beans using JndiObjectFactoryBean.

Following configuration works well on local Jetty, but doesn’t work deployed on WebLogic server.

<jee:jndi-lookup id="connectionFactory" jndi-name="jms-cf"></jee:jndi-lookup>
<jee:jndi-lookup id="replyQueue" jndi-name="jms-queue0"></jee:jndi-lookup>
<jee:jndi-lookup id="requestQueue" jndi-name="jms-queue1"></jee:jndi-lookup>

But with this configuration, everything is fine.

<bean id="connectionFactory">
  <property name="jndiName" value="jms-cf"></property>
</bean>

<bean id="replyQueue">
  <property name="jndiName" value="jms-queue0"></property>
</bean>
<bean id="requestQueue">
  <property name="jndiName" value="jms-queue1"></property>
</bean>

Little bit strange :-)

]]>
http://www.xpj.cz/expee/2009/06/difference-between-jeejndi-lookup-and-jndiobjectfactorybean/feed/ 0
Configuring Jetty with ActiveMQ and JNDI http://www.xpj.cz/expee/2009/06/configuring-jetty-with-activemq-and-jndi/ http://www.xpj.cz/expee/2009/06/configuring-jetty-with-activemq-and-jndi/#comments Thu, 04 Jun 2009 08:54:23 +0000 xpj http://www.xpj.cz/expee/?p=7 Java

For development of Message Driven POJOs (see cute tutorial on Spring blogs) I need some testing environment with running JMS server. As I’m using Maven and his Jetty plugin, I found following solution.

Configuring Jetty

For configuring Jetty with JNDI, we need to place some configuration options into its configuration files. There are three options:

  1. jetty.xml
  2. WEB-INF/jetty-env.xml
  3. context xml file

For me, the most easiest way is to use the jetty-env.xml in WEB-INF directory. So I created this file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">

<Configure id="wac">

 <New id="connectionFactory">
   <Arg>jms/connectionFactory</Arg>
   <Arg>
     <New>
       <Arg>tcp://localhost:61616</Arg>
     </New>
   </Arg>
 </New>

 <New id="requestQueue">
   <Arg>jms/requestQueue</Arg>
   <Arg>
     <New>
       <Arg>requestQueue</Arg>
     </New>
   </Arg>
 </New>

 <New id="replyQueue">
   <Arg>jms/replyQueue</Arg>
   <Arg>
     <New>
       <Arg>replyQueue</Arg>
     </New>
   </Arg>
 </New>

</Configure>

Next step is to setup resources in web.xml file to use this JNDI resources.

<resource-ref>
   <description>Connection Factory</description>
   <res-ref-name>jms/connectionFactory</res-ref-name>
   <res-type>javax.jms.QueueConnectionFactory</res-type>
   <res-auth>Container</res-auth>
 </resource-ref>

 <resource-env-ref>
   <resource-env-ref-name>jms/requestQueue</resource-env-ref-name>
   <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
 </resource-env-ref>
 <resource-env-ref>
   <resource-env-ref-name>jms/replyQueue</resource-env-ref-name>
   <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
 </resource-env-ref>

Configuring Spring context.xml

The hardest stuff is behind us :-) Just now, we can use the jee schema for configuring beans.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:jee="http://www.springframework.org/schema/jee"
 xmlns:amq="http://activemq.apache.org/schema/core"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd">

 <jee:jndi-lookup id="connectionFactory" jndi-name="javax.jms.QueueConnectionFactory"></jee:jndi-lookup>
 <jee:jndi-lookup id="replyQueue" jndi-name="Queue-0"></jee:jndi-lookup>
 <jee:jndi-lookup id="requestQueue" jndi-name="Queue-1"></jee:jndi-lookup>

</beans>

Running

Don’t forget to start your ActiveMQ server and than just fire up maven jetty:run. But it will work better, if you use following snippet in your pom file :-)

<plugin>
 <groupId>org.mortbay.jetty</groupId>
 <artifactId>maven-jetty-plugin</artifactId>
 <version>6.1.10</version>
 <configuration>
   <scanIntervalSeconds>10</scanIntervalSeconds>
   <stopKey>foo</stopKey>
   <stopPort>9999</stopPort>
 </configuration>
 <executions>
   <execution>
     <id>start-jetty</id>
     <phase>process-test-classes</phase>
     <goals>
       <goal>run</goal>
     </goals>
     <configuration>
       <scanIntervalSeconds>0</scanIntervalSeconds>
       <daemon>true</daemon>
     </configuration>
   </execution>
   <execution>
     <id>stop-jetty</id>
     <phase>test</phase>
     <goals>
       <goal>stop</goal>
     </goals>
   </execution>
 </executions>
 <dependencies>
   <dependency>
     <groupId>org.apache.activemq</groupId>
     <artifactId>activemq-core</artifactId>
     <version>5.2.0</version>
   </dependency>
   <dependency>
     <groupId>org.apache.xbean</groupId>
     <artifactId>xbean-spring</artifactId>
     <version>2.8</version>
   </dependency>
 </dependencies>
 </plugin>
]]>
http://www.xpj.cz/expee/2009/06/configuring-jetty-with-activemq-and-jndi/feed/ 0