I have a collection of related photos stored on my PC. The filenames were “ugly” – standard file names coming from the photo camera. I would like to rename them into a file containing the date when the photo was shoot, e.g. 2011.07.21.jpg. There is an excellent commandline tool to do just that – renrot. It’s packaged for Debian & Ubuntu so to install it, I’ve simply run:

apt-get install renrot

Then, in the directory that contains my photos I’ve run:

renrot -n "%Y.%m.%d" *

-n option allows for specifying the template used for renaming the files – it is year, month and day separated with dots in my case. If the tool creates more files, you can remove the originals:

rm *orig

Refer to manual page for the full options!


Introduction

In this blog we’ll be looking at how to use hibernate tools with just ant. This may be useful if you need to plug some hibernate tasks into your build system or have them scripted in any way. We will create a stand-alone ant build file with the minimum number of required libraries.

Libraries

I’ve extracted hibernate tools jar from eclipse hibernate plugin. You can find it in your eclipse installation directory, under plugins:
plugins/org.hibernate.eclipse_X.X.X.X/lib/tools. Take hibernate-tools.jar and freemarker.jar. From plugins/org.hibernate.eclipse_X.X.X.X/lib/hibernate grab more jars:

  • dom4j-1.6.1.jar
  • log4j-1.2.15.jar
  • slf4j-api-1.5.8.jar
  • slf4j-log4j12-1.5.8.jar

You will also need org.apache.commons.logging.jar and JDBC driver. I use MySQL, so I’ve added mysql-connector-java-5.1.13.jar as well. Put all the jars into “lib” directory. Create other directories: classes, src and generated. Or don’t bother – download the whole lot as I’ve set it up.

Java entities

We will use two sample entity classes (POJOs) for that example: Password and Resource. A Resource can contain many Passwords.

public class Password implements Serializable {
        private static final long serialVersionUID = 1L;
        private int id;
        private String password;
 
        // many-to-one association to Resource
        private Resource resource;
 
        public Password() {
        }
        public int getId() {
                return this.id;
        }
        public void setId(int id) {
                this.id = id;
        }
        public String getPassword() {
                return this.password;
        }
        public void setPassword(String password) {
                this.password = password;
        }
        public Resource getResource() {
                return this.resource;
        }
        public void setResource(Resource resource) {
                this.resource = resource;
        }
}
public class Resource implements Serializable {
        private static final long serialVersionUID = 15146339L;
        private int id;
        private String name;
 
        public Resource() {
        }
        public int getId() {
                return this.id;
        }
        public void setId(int id) {
                this.id = id;
        }
        public String getName() {
                return this.name;
        }
        public void setName(String name) {
                this.name = name;
        }
}

Hibernate configuration

Next, let’s create simple hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
<session-factory>
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost/hibernatetutorial</property>
  <property name="hibernate.connection.username">root</property>
  <property name="hibernate.connection.password">****</property>
  <property name="hibernate.connection.pool_size">10</property>
  <property name="show_sql">true</property>
  <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.hbm2ddl.auto">update</property>
  <!-- Mapping files -->
  <mapping resource="password.hbm.xml"/>
  <mapping resource="resource.hbm.xml"/>
</session-factory>
</hibernate-configuration>

…and mapping files for password and resource.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping>
        <class name="net.opensesam.entity.Password" table="password">
                <id name="id" type="long" column="ID" />
                <many-to-one name="resource_id" class="net.opensesam.entity.Resource" />
                <property name="password">
                        <column name="password" />
                </property>
        </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping>
  <class name="net.opensesam.entity.Resource" table="resource">
   <id name="id" type="long" column="ID" />
   <property name="name">
     <column name="name" />
   </property>
 </class>
</hibernate-mapping>

Ant build file

Finally we can build build.xml! We’ll first add paths to the required jars, then define new task: hibernatetool. We can then use our new task via <hibernatetool> tag – see the code below, it’s pretty self-explanatory.

<project name="MyProject" basedir="." default="default">
<path id="toolslib">
<path location="lib/dom4j-1.6.1.jar" />
<path location="lib/freemarker.jar" />
<path location="lib/hibernate3.jar" />
<path location="lib/hibernate-tools.jar" />
<path location="lib/log4j-1.2.15.jar" />
<path location="lib/org.apache.commons.logging.jar" />
<path location="lib/slf4j-api-1.5.8.jar" />
<path location="lib/slf4j-log4j12-1.5.8.jar" />
<path location="lib/mysql-connector-java-5.1.13.jar" />
</path>
 
<taskdef name="hibernatetool" 
         classname="org.hibernate.tool.ant.HibernateToolTask" 
         classpathref="toolslib" />
 
<target name="default">
<hibernatetool destdir="./generated">
 <classpath>
  <path location="." />
  <path location="./classes" />
 </classpath>
 
 <configuration configurationfile="hibernate.cfg.xml"/>
 <hbm2ddl export="false" outputfilename="sql.ddl"/>
</hibernatetool>
</target>
</project>

We are running above hbm2ddl task to export database schema into ./generated/sql.ddl file. Other tasks you can use are:

  • hbm2java – generate POJOs
  • hbm2dao – generate DAOs
  • hbmtemplate – generate any custom code you want using templates (aka scaffolding)

Refer to the documentation for more details.

Hibernate annotations

If you prefer to use hibernate annotations, you need to do few changes. Add two extra jars:

  • hibernate-annotations-3.5.6-Final.jar
  • hibernate-jpa-2.0-api-1.0.0.Final.jar

Change <configuration> tag into <annotationconfiguration>:

 <annotationconfiguration configurationfile="hibernate.cfg.xml"/>

Your hibernate.cfg.xml will obviously need to contain pointers to annotated classes, e.g.:

  <mapping class="net.opensesam.entity.Password" />

I have it configured with the open source project “Open Sesame” – you can see the whole configuration in git repository.

You can also download a full source code for the non-annotated example.


Introduction

Remember me functionality is a mechanism that lets users log in automatically, even when they re-start their browser. In other words: after their session cookie is deleted by the browser (which is normally after closing the browser). This is implemented by setting up another cookie that will live in the browser’s database for a longer period (e.g. weeks). Spring out of the box offers two implementations of this feature. This tutorial presents two different approaches to cookie creation: hash-based token and persistent token. We will only look into the remember-me part of the Spring Security configuration, if you need more information look at basic setup.

Hash-based token

Implemented by org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices, it creates a base64 encoded cookie that contains:

  • username – you will be logged in as this username, if cookie is confirmed to be authentic.
  • expiryTime – Spring will treat cookie as invalid after expiry time. The cookie is set to be valid for 2 weeks when created.
  • hash – md5 hash of 2 values above, user’s password, and a key.

Hash is used to confirm that cookie is valid – e.g. no-one has tried to tweak the cookie manually. A key is a very important variable here – we set it in Spring’s configuration and it should be a unique, secret for our application. As nobody knows what key we have picked, no one will be able to generate valid hash. The above also means that:

  • There is no extra information stored on the server side.
  • If cookie is intercepted by an attacker, it can be used to log in as valid user.
  • Username is exposed in cookie and can be read
  • Cookie becomes invalid when user changes password.

The configuration itself is trivial, simply add one line with <remember-me> tag to security.xml (again, refer to the previous post for basics):

<http auto-config="true" >
		<remember-me key="...verylonganduniquekey..." />
		<intercept-url pattern="/*" access="ROLE_USER" />
	</http>

This automatically adds a new checkbox to the standard login form.

Login_form

Once you login, notice additional cookie created: SPRING_SECURITY_REMEMBER_ME_COOKIE.

Cookies

To test functionality, delete JSESSIONID cookie and refresh. Normally that would effectively result in a logging out but with our “remember me” cookie, new JSESSIONID is created straight away.

Persistent token

A better solution to remember me cookie is to use totally random string that will be stored as a cookie and has no meaningful data in itself. The disadvantage is that it requires storing some information on the server side. When token is presented from user’s browser, it is matched against a record in table with all tokens. Our Spring configuration will change only a bit.

<http auto-config="true" >
		<remember-me data-source-ref="dataSource" />
		<intercept-url pattern="/*" access="ROLE_USER" />
	</http>

We will also need a table “persistent_logins” to store tokens. For MySQL you can use following SQL.

CREATE TABLE IF NOT EXISTS `persistent_logins` (
  `username` VARCHAR(64) DEFAULT NULL,
  `series` VARCHAR(64) NOT NULL DEFAULT '',
  `token` VARCHAR(64) DEFAULT NULL,
  `last_used` datetime DEFAULT NULL,
  PRIMARY KEY (`series`)
)

As you can see there are actually two new pieces there: series and token. Both are random strings and both are passed back to user and stored in the cookie. The idea here is that token will be changed on every “remember me” login, so when a user comes with valid series but invalid token – the chances are that the cookie has been stolen and used for authentication! We could not prevent stealing the cookie but we can at least:

  • warn user
  • invalidate all tokens for current user

And this is exactly what Spring Security is doing.


Sometimes it might be very convenient to be able to debug application deployed on web server. This tutorial presents how to do it, if the application is deployed using Jetty plugin for Maven or Tomcat servers.

Jetty Maven plugin

Set the following MAVEN_OPTS to the following:

export MAVEN_OPTS='-Xdebug -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=y'

Run Jetty Maven plugin:

mvn jetty:run

Sample setting of the development environment can be found here: Eclipse environment for convenient development of Java web application using Maven, Spring, Struts2, and Hibernate running on Jetty server.

Tomcat

Use default options of Tomcat which are

-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n

or set JPDA_OPTS using the following command:

export JPDA_OPTS='-agentlib:jdwp=transport=dt_socket,address=4000,server=y,suspend=y'

Run Tomcat:

catalina jpda start

Arguments

Here is list of parameters for the debugging.

  • Xdebug – Start the JVM and listen for debugging connections.
  • Xrunjdwp – The remote debugging connection parameters.
  • transport=dt_socked – Use sockets.
  • address=4000 – The port to connect to or the shared memory address to use.
  • server=y – Start in server mode.
  • suspend=y – If ‘n’ don’t wait for a debugger to be attached. If ‘y’ your application will lunch only when you run your debugger.

Debugging in Eclipse

Go to: Debug -> Debug Options…
Select: Remote Java Application
Select project
Use the same port as defined in ‘address’

Debug configuration

Click: Debug

If ‘suspend=y’ then your application should start. At this stage when you put any break point in Eclipse, your application should stop there.

References

Please refer to:


Introduction

In the tutorial below we will look at a basic integration of a Java web application with Spring Security 3. In this particular scenario we’ll be integrating Spring Security with existing web application that uses Struts & Spring. However, similar steps can be applied to any other web framework you may be using. We will also look at one of the core concepts Spring Security – AccessDecisionManager.

Basic integration

We will start with an application that has no security implemented. I’ve used this setup as my base. It already uses maven, so the first thing we do is to add a new repository:

<repository>
			<id>org.springframework.security</id>
			<name>Spring Security</name>
			<url>http://maven.springframework.org/snapshot</url>
		</repository>

and bunch of new JARs:

<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-core</artifactId>
			<version>3.0.6.CI-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>3.0.6.CI-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>3.0.6.CI-SNAPSHOT</version>
		</dependency>

Spring Security is implemented as a filter – it can be plugged into the application without any changes. A request will be intercepted by DelegatingFilterProxy and authentication will take place, as defined in Spring security XML file. We will add filter to the top of web.xml and trigger it for all URLs (url pattern set to /*).

<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
 	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>*</url-pattern>
	</filter-mapping>

For the very basic integration, Spring Security will require only little configuration that we’ll put into security.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/security 
		http://www.springframework.org/schema/security/spring-security-3.0.xsd
	">
	<http auto-config="true">
		<intercept-url pattern="/*" access="ROLE_USER" />
	</http>
	<authentication-manager alias="authenticationManager">
		<authentication-provider>
			<user-service>
				<user authorities="ROLE_USER" name="guest" password="test" />
			</user-service>
		</authentication-provider>
	</authentication-manager>
</beans:beans>

We are defining here that access to any resource (intercept-url pattern=”/*”) should be allowed only for users that have authority called ROLE_USER. Normally user credentials will need to be stored in a central place – typically a database or LDAP server. Above we are hard-coding an authentication-provider with one user (guest/test) that has authority ROLE_USER.

Finally, we need to tell Spring about security.xml. Since our application already uses Spring, we have defined in web.xml contextConfigLocation parameter already – it points to our beans definition (applicationContext.xml). We will add security.xml in the same place:

<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
		/WEB-INF/resources/applicationContext.xml
		/WEB-INF/resources/security.xml
		</param-value>
	</context-param>

When we build the application now, any URL should automatically generate following login page:

Login_page

Access decision manager

Spring Security deals (or helps you deal with) two security concepts: first authentication and then authorization. Authentication filters are run first – they will make sure that a user is who he says he is. This is usually done by checking user credentials, e.g., username and password). Let’s skip authentication step for now and talk about authorization. Authorization takes care of deciding if authenticated user (meaning that authentication must precede authorization) should be allowed to access a resource.

Spring Security supports authorization with the help of AccessDecisionManager interface. AccessDecisionManagers in turn will use one or more AccessDecisionVoters. Each voter will make the decision about granting or denying the access for given user to given resource. Access decision manager will aggregate the votes and issue final decision. Voters can return: ACCESS_GRANTED,ACCESS_DENIED but also ACCESS_ABSTAIN if a voter can’t or doesn’t want to make a decision. Managers must make the final decision – user is either granted access or not. The “not granting the access” part is done by throwing an exception – usually AccessDeniedException. In the default configuration that we’ve created, Spring uses implementation of AccessDecisionManager called AffirmativeBased. It will grant the access if any voter returns ACCESS_GRANTED. The default voters are

  • RoleVoter – checks GrantedAuthority (remember user tag with authorities=”ROLE_USER”) against ConfigAttribute (that comes from intercept-url pattern=”/*” access=”ROLE_USER”)
  • AuthenticatedVoter – can check if user IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED or IS_AUTHENTICATED_ANONYMOUSLY. This is not used in our setup

We can see authorization in working when we enable higher logging level – simply add to log4j properties:

log4j.logger.org.springframework.security=DEBUG, console

When we try to access protected page as anonymous user, among other messages we can see following entries, with AccessDeniedException thrown at the end. RoleVoter returns ACCESS_DENIED and AuthenticatedVoter returns ACCESS_ABSTAIN.

 DEBUG | 2011-07-10 12:40:30,473 | AffirmativeBased.java | decide | 53 | Voter: org.springframework.security.access.vote.RoleVoter@1ae73783, returned: -1
 DEBUG | 2011-07-10 12:40:30,474 | AffirmativeBased.java | decide | 53 | Voter: org.springframework.security.access.vote.AuthenticatedVoter@41ed8741, returned: 0
 DEBUG | 2011-07-10 12:40:30,478 | ExceptionTranslationFilter.java | handleException | 153 | Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied

Compare it with the log after we provide correct credentials. This time RoleVoter returns ACCESS_GRANTED and as soon as it happens, AffirmativeBased access decision manager stops querying voters and allows for access:

  DEBUG | 2011-07-10 12:43:33,468 | AffirmativeBased.java | decide | 53 | Voter: org.springframework.security.access.vote.RoleVoter@1ae73783, returned: 1
 DEBUG | 2011-07-10 12:43:33,469 | AbstractSecurityInterceptor.java | beforeInvocation | 213 | Authorization successful

There are other implementations of AccessDecisionManagers and AccessDecisionVoters but I think we will leave them for another time. Stay tuned!

Here is a full source code for the example above. Run it with:

mvn jetty:run

Introduction

When developing web application set up of convenient development environment might be crucial for more efficient work. Let’s consider web application that uses following frameworks:

In addition we want to use Eclipse as our editor.

This tutorial presents initial setting of Eclipse project to support all the frameworks mentioned above and allow the convenient and fast application development of web application on Jetty server.

[ad#adsense]

Create Eclipse project

First step is to create Ecplise project, e.g., Dynamic Web Project, that would have the following structure:

initial_project_structure.png

Make sure that ‘src/main/java’ and ‘test/main/java’ are your source folders on building path and default output folder is ‘target/classes’.

build_path.png

Complete Eclipse project can be downloaded here:

Spring_Security_zip

Configure Maven

Maven configuration is in ‘pom.xml’ file. It consists of:

  • list of ‘repositories’
  • list of ‘pluginRepositories’
  • list of ‘dependencies’
  • ‘build’ settings, i.e., ‘resources’ and ‘plugins’
  • list of ‘plugins’

Make sure that:

  • ‘packaging’ is set to ‘war’

Crucial plugins

maven-war-plugin. The WAR Plugin is responsible for collecting all artifact dependencies, classes and resources of the web application and packaging them into a web application archive.

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-war-plugin</artifactId>
	<configuration>
		<archive>
			<manifest>
				<addClasspath>true</addClasspath>
				<classpathPrefix>lib/</classpathPrefix>
			</manifest>
		</archive>
		<webResources>
			<resource>
				<!-- this is relative to the pom.xml directory -->
				<directory>src/main/webapp</directory>
				<targetPath>/</targetPath>
				<!-- enable filtering -->
				<filtering>false</filtering>
			</resource>
		</webResources>
	</configuration>
</plugin>

maven-jetty-plugin. In order to run Jetty on a webapp project which is structured according to the usual Maven defaults.

<plugin>
	<groupId>org.mortbay.jetty</groupId>
	<artifactId>maven-jetty-plugin</artifactId>
	<version>6.1.10</version>
	<configuration>
		<scanIntervalSeconds>5</scanIntervalSeconds>
		<stopKey>stop</stopKey>
		<stopPort>9999</stopPort>
		<scanTargets>
			<scanTarget>src/</scanTarget>
		</scanTargets>
	</configuration>
</plugin>

pom.xml

Configuration of ‘pom.xml‘ is presented below:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>net.zabuchy</groupId>
	<artifactId>SpringSecurity</artifactId>
	<version>0.1</version>
	<packaging>war</packaging>
	<name>SpringSecurity</name>
	<url>http://www.zabuchy.net</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<repositories>
		<repository>
			<id>central</id>
			<name>Maven Repository Switchboard</name>
			<layout>default</layout>
			<url>http://repo1.maven.org/maven2</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
		<!-- I know people complains about java.net repository, but it solves dependencies 
			to JEE so... -->
		<repository>
			<id>java.net</id>
			<name>Java.net Maven Repository</name>
			<url>http://download.java.net/maven/2</url>
			<releases>
				<enabled>true</enabled>
				<updatePolicy>always</updatePolicy>
				<checksumPolicy>warn</checksumPolicy>
			</releases>
			<snapshots>
				<enabled>false</enabled>
				<updatePolicy>never</updatePolicy>
				<checksumPolicy>fail</checksumPolicy>
			</snapshots>
		</repository>
		<repository>
			<id>jboss-public-repository-group</id>
			<name>JBoss Public Repository Group</name>
			<url>http://repository.jboss.org/nexus/content/groups/public/</url>
			<layout>default</layout>
			<releases>
				<enabled>true</enabled>
				<updatePolicy>never</updatePolicy>
			</releases>
			<snapshots>
				<enabled>true</enabled>
				<updatePolicy>never</updatePolicy>
			</snapshots>
		</repository>
		<repository>
			<id>com.springsource.repository.bundles.release</id>
			<name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name>
			<url>http://repository.springsource.com/maven/bundles/release</url>
		</repository>
		<repository>
			<id>com.springsource.repository.bundles.external</id>
			<name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
			<url>http://repository.springsource.com/maven/bundles/external</url>
		</repository>
		<repository>
			<id>com.springsource.repository.libraries.release</id>
			<name>SpringSource Enterprise Bundle Repository - SpringSource Library Releases</name>
			<url>http://repository.springsource.com/maven/libraries/release</url>
		</repository>
		<repository>
			<id>com.springsource.repository.libraries.external</id>
			<name>SpringSource Enterprise Bundle Repository - External Library Releases</name>
			<url>http://repository.springsource.com/maven/libraries/external</url>
		</repository>
		<repository>
			<id>org.springframework.security</id>
			<name>Spring Security</name>
			<url>http://maven.springframework.org/snapshot</url>
		</repository>
 
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>jboss-public-repository-group</id>
			<name>JBoss Public Repository Group</name>
			<url>http://repository.jboss.org/nexus/content/groups/public/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>
	<!-- Please add dependencies alphabetically so we can detect duplicates -->
	<dependencies>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib-nodep</artifactId>
			<version>2.2</version>
		</dependency>
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2.1</version>
		</dependency>
		<dependency>
			<groupId>com.jgeppert.struts2.jquery</groupId>
			<artifactId>struts2-jquery-plugin</artifactId>
			<version>2.4.0</version>
		</dependency>
		<dependency>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
			<version>3.8.0.GA</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.0</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.1</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.0</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-json-plugin</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-annotations</artifactId>
			<version>3.5.6-Final</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>3.5.6-Final</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.13</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.6.1</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-simple</artifactId>
			<version>1.6.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>3.0.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>3.0.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>3.0.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>3.0.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>3.0.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>3.0.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-core</artifactId>
			<version>3.0.6.CI-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>3.0.6.CI-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>3.0.6.CI-SNAPSHOT</version>
		</dependency>
	</dependencies>
 
	<build>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>false</filtering>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<configuration>
					<archive>
						<manifest>
							<addClasspath>true</addClasspath>
							<classpathPrefix>lib/</classpathPrefix>
						</manifest>
					</archive>
					<webResources>
						<resource>
							<!-- this is relative to the pom.xml directory -->
							<directory>src/main/webapp</directory>
							<targetPath>/</targetPath>
							<!-- enable filtering -->
							<filtering>false</filtering>
						</resource>
					</webResources>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.mortbay.jetty</groupId>
				<artifactId>maven-jetty-plugin</artifactId>
				<version>6.1.10</version>
				<configuration>
					<scanIntervalSeconds>5</scanIntervalSeconds>
					<stopKey>stop</stopKey>
					<stopPort>9999</stopPort>
					<scanTargets>
						<scanTarget>src/</scanTarget>
					</scanTargets>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Configure Deployment Descriptor

Configuration of ‘web.xml‘ is presented below:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
	<display-name>SpringSecurity</display-name>
 
	<!-- Struts2 filter -->
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>*.action</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/struts/*</url-pattern>
	</filter-mapping>
 
	<!-- Spring beans -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
		/WEB-INF/resources/applicationContext.xml
		</param-value>
	</context-param>
 
	<!-- log4j -->
	<context-param>
		<param-name>log4jConfigLocation</param-name>
		<param-value>/WEB-INF/resources/log4j.properties</param-value>
	</context-param>
 
	<listener>
		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>
 
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

Configure log4j

Configuration of ‘log4j.properties‘ is presented below:

### direct log messages to stdout ###
log4j.rootLogger=ERROR, file
 
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%6p | %d | %F | %M | %L | %m%n
 
# AdminFileAppender - used to log messages in the admin.log file.
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=target/SpringSecurity.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%6p | %d | %F | %M | %L | %m%n
 
log4j.logger.net.zabuchy=DEBUG, console

Configure Spring beans

Configuration of Spring beans should be placed in ‘applicationContext.xml’ file. In this project Spring beans configuration files were included in ‘applicationContext.xml’ file. ‘beans.xml’ defines ‘outcomeAction’ bean, which represents Struts2 action and other beans required by this action, i.e., ‘outcomeDeterminer’. ‘databaseBeans.xml’ includes configuration of beans required by Hibernate. ‘dataSource’ bean includes configuration of database to be used in this project. It should be changed accordingly. ‘sessionFactory’ bean includes configuration of Hibernate like dataSource (pointing to ‘dataSource’ bean) and packagesToScan for @Entity beans. Content of the files is presented below.

applicationContext.xml‘ file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
	<import resource="spring/beans.xml" />
	<import resource="spring/databaseBeans.xml" />
 
</beans>

spring/beans.xml‘ file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  http://www.springframework.org/schema/aop   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 
	<bean class="net.zabuchy.actions.OutcomeAction" id="outcomeAction"
		scope="session">
		<property name="outcomeDeterminer" ref="outcomeDeterminer" />
		<aop:scoped-proxy />
	</bean>
 
	<bean class="net.zabuchy.business.OutcomeDeterminer" id="outcomeDeterminer">
		<aop:scoped-proxy />
	</bean>
 
</beans>

spring/databaseBeans.xml‘ file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
	<!-- Data source configuration -->
	<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
		id="dataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://127.0.0.1:3306/db" />
		<property name="username" value="test" />
		<property name="password" value="test" />
	</bean>
 
	<!-- Hibernate session factory -->
	<bean
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
		id="sessionFactory">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<!-- In prod set to "validate", in test set to "create-drop" -->
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<!-- In prod set to "false" -->
				<prop key="hibernate.show_sql">false</prop>
				<!-- In prod set to "false" -->
				<prop key="hibernate.format_sql">true</prop>
				<!-- In prod set to "false" -->
				<prop key="hibernate.use_sql_comments">true</prop>
				<!-- In prod set to "false", in test set to "true" -->
				<prop key="hibernate.cache.use_second_level_cache">false</prop>
			</props>
		</property>
		<property name="packagesToScan" value="net.zabuchy" />
	</bean>
 
</beans>

Configure Struts2 actions

Struts2 actions are defined in ‘struts.xml‘ file, which is presented below. ‘getOutcome’ action uses ‘outcomeAction’ bean configuration and invokes ‘getOutcome’ method from this bean. If ‘getOutcome’ method returns ‘success’,'success.jsp’ will be displayed. If ‘getOutcome’ method returns ‘error’,'error.jsp’ will be displayed.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
                        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<constant name="struts.devMode" value="true" />
	<package extends="struts-default" name="default">
 
		<global-results>
			<result name="error">error.jsp</result>
		</global-results>
 
		<action class="outcomeAction" method="getOutcome" name="getOutcome">
			<result name="success">/WEB-INF/content/success.jsp</result>
		</action>
 
	</package>
</struts>

Implement Java classes

Sample Java classes code, which was used in this project is presented below. Two classes were created and defined as Spring beans in ‘beans.xml’ file: ‘OutcomeAction’, which is Struts2 action and ‘OutcomeDeterminer’, which is class used by this action.

OutcomeAction.java‘ file in package net.zabuchy.actions

package net.zabuchy.actions;
 
import net.zabuchy.business.OutcomeDeterminer;
import org.apache.struts2.dispatcher.DefaultActionSupport;
 
public class OutcomeAction extends DefaultActionSupport {
	private static final long serialVersionUID = 4794228472575863567L;
 
	private OutcomeDeterminer outcomeDeterminer;
 
	public String getOutcome() {
		return outcomeDeterminer.getOutcome();
	}
 
	public OutcomeDeterminer getOutcomeDeterminer() {
		return outcomeDeterminer;
	}
 
	public void setOutcomeDeterminer(OutcomeDeterminer outcomeDeterminer) {
		this.outcomeDeterminer = outcomeDeterminer;
	}
}

OutcomeDeterminer.java‘ file in package net.zabuchy.business

package net.zabuchy.business;
 
import java.util.Random;
import org.apache.log4j.Logger;
 
public class OutcomeDeterminer {
 
	private static final Logger logger = Logger.getLogger(OutcomeDeterminer.class
			.getName());
 
	private Random generator;
 
	public OutcomeDeterminer() {
		generator = new Random();
	}
 
	public String getOutcome() {
		int randomNumber = generator.nextInt(5);
		if (logger.isDebugEnabled()) {
			logger.debug("Random number is: " + randomNumber);
		}
 
		if (randomNumber == 0) {
			return "error";
		}
		return "success";
	}
}

Add libraries to Eclipse

The easiest way to add required libraries to Eclipse is allow Maven to download all the required libraries (defined as dependencies in pom.xml) and add them to ‘Referenced Libraries’. In order to do so in root directory of the application run:

mvn package

This command should build war package to be deployed on web server including:

  • downloading required libraries and coping them to ‘target/{projectName}/WEB-INF/lib’ (configured in ‘manifest’ section of maven-war-plugin)
  • compiling classes and coping them to ‘target/{projectName}/WEB-INF/classes’
  • coping files from ‘src/main/resource’ to ‘target/{projectName}/WEB-INF/classes’
  • coping files from ‘src/main/webapp’ to ‘target/{projectName}’ (configured in ‘webResources’ section of maven-war-plugin)

Target

In Eclipse add libraries from ‘target/{projectName}/WEB-INF/lib’ to build path. It might be required to move them to the top ‘Order and Export’.

Libraries

Run application

We are going to use jetty server to run the application. ‘jetty:run’ command allows the automatic reloads, so during development the changes done in Eclipse are automatically deployed to the server. In order to run the application type:

mvn jetty:run

maven-jetty-plugin automatically scans ‘src’ (configured in ‘scanTargets’ section of maven-jetty-plugin) every 5 seconds (configured in ‘scanIntervalSeconds’ section of maven-jetty-plugin) for changes.

To deploy the project on different web server, e.g., Tomcat, just use ‘mvn package’ command and copy war file to appropriate directory on your Tomcat server.

In your web browser access the following link: ‘http://localhost:8080/SpringSecurity/getOutcome.action’. You should be able to see either success or error page.


Sometimes simply checking the size of the whole directory is not enough, and you need more information, e.g. the whole directory has 3GB – but how much of it are those .avi files inside? The most flexible way for matching the files (or directories) is by using find command, so let’s build the solution based on this. For the actual counting of the file sizes, we can use du.

Consider directory as follows. Numbers in the brackets are the file sizes.

% tree -s filesizes    
filesizes
|-- [        116]  config.xml
|-- [        290]  config.yml
|-- [       4096]  dir1
|   |-- [       4096]  backup
|   |   `-- [      20583]  backup.tar.gz
|   |-- [          5]  blah space.yml
|   |-- [       2858]  script.php
|   `-- [       2858]  script.py
|-- [       4096]  dir2
|   `-- [       4096]  backup
|       `-- [      20583]  backup.tar.gz
`-- [       4096]  dir3
    `-- [       4096]  backup
        |-- [       4096]  backup
        |   `-- [      20583]  backup.tar.gz
        `-- [      20583]  backup.tar.gz
 
7 directories, 9 files

Size of the whole directory (-b option gives the size in bytes):

% du -sb filesizes
121227	filesizes

Total size of selected files

Let’s calculate the size of all the yml files. They are stored in different sub-directories and one of them contains a whitespace in the name (blah space.yml). find part of the command is straight-forward:

% find filesizes -type f -name '*yml'
filesizes/dir1/blah space.yml
filesizes/config.yml

Find all files (-type f) with the name ending with yml (-name ‘*yml’) in filesizes directory (that’s first argument – if it’s omitted then find will work from the current directory).
To join it with du command we will change the output of find to separate files it finds with NULL character (0) instead of default newline. We will also pass the list of files to du command, and instruct it that the items (files) are coming in the NULL-separated list from standard input:

% find filesizes -type f -name '*yml' -print0 | du -cb --files0-from=-
5	filesizes/dir1/blah space.yml
290	filesizes/config.yml
295	total

-c switch for du generates the last line, with the total count.

Total size of selected directories

Let’s try something a (little) bit more tricky – calculate the total size of all sub-directories, matched by a pattern. In our example, I would like to know the total size of all backup directories. Notice, that dir3 has backup sub-directory, which in turn has backup sub-directory. We don’t want to count those as two separate entries and sum them up by accident – that would bump our total size (you could possibly get the size of all backup directories bigger than the size of the whole top level directory!).

% find filesizes -type d -name backup -prune -print0 | du -csb --files0-from=-
24679	filesizes/dir1/backup
49358	filesizes/dir3/backup
24679	filesizes/dir2/backup
98716	total

This time we’re find-ing only directories (-type d) and once we find one, we stop and don’t go into it’s sub-directories (-prune). On the du side we’ve added -s switch that produces the summarized total for each item (directory) it gets.


One of the easiest methods of optimizing the execution of PHP script is by using a static variable. Imagine a function that does some complex calculations, possibly executes several database queries. If the return value from the function does not change too often and the function may be called several times during single request, it may be beneficial to cache the return value with static variable,
You could implement it within your complex function or with a wrapper function if you’re trying to cache the function you didn’t write.

function mymodule_complex_calculation() {
  static $cache;
  if (isset($cache)) {
    return $cache;
  }
  // Otherwise we need to perform our calculations
  // ...some complex calculation that returns 
  $cache = complex_calculation();
  return $cache;
}

This is a very simple pattern and cached data will “survive” only single web request but it may still be very effective, especially if function is called many times during the same request. Drupal implements a drupal_static() function that is a serves as centralized place for storing static variables. The advantage over using your own static variable is that data stored by drupal_static() can be reset. It means that, if other piece of code decides that some cached variable should be cleaned in mid-request, it can do so. Function definition is:

function &drupal_static($name, $default_value = NULL, $reset = FALSE)

You will need a unique name to address the data you want to cache. This will really become a key in the static array. The customary way in Drupal is to use the name of your function as $name, you can use PHP’s magic constant __FUNCTION__ that resolves to current function name. Now we can update our function as follows:

function mymodule_complex_calculation() {
  $cache = &drupal_static(__FUNCTION__);
  if (isset($cache)) {
    return $cache;
  }
  // Otherwise we need to perform our calculations
  // ...some complex calculation that returns simple value
  $cache = complex_calculation();
  return $cache;
}

You may notice that we don’t use drupal_static() to actually set the data – and we don’t need to! As soon as we assign anything to $cache, it will end up in our centralized static store.
drupal_static() has one disadvantage – it adds a new function call (plus execution of some logic inside drupal_static()) every time you use cache which increases the execution time. Compare it with the listing 1 – much simpler. This will add some overhead to each call. At this level we are talking about micro optimizing. It will make noticeable difference only if you function is called hundreds (or thousands) of times per request. If that’s the case, you can use advanced usage pattern for drupal_static. It merges functionality of our 2 functions:

function my_funct() {
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    //17 is the default value in case the cache was empty
    $drupal_static_fast['cache'] = &drupal_static(__FUNCTION__,17);
  }
  $cache = &$drupal_static_fast['cache'];
  //do whatever you need with $cache ...

Pay attention to the fact that $drupal_static_fast is an array and the actual cache is within that array ($drupal_static_fast['cache']). You have to use an array, otherwise your reference to the static variable will be lost and each time my_funct() is called, it will need to retrieve a value using drupal_static() – therefore negating our optimization (see manual for the details).
I’ve added a benchmark for it to micro-optimization site. Assuming I’ve got the test right, you can see the 17x difference between accessing static variable vs calling drupal_static() function.


Apache log4j is one of the most popular frameworks used for logging events within Java code. Apache CXF on the other hand is one of the most popular framework to support communication using web services.

To monitor and debug Java application there might be a need to log inbound and outbound web service messages.
If we use two frameworks mentioned above org.apache.cxf.interceptor.LoggingInInterceptor and
org.apache.cxf.interceptor.LoggingOutInterceptor might be configured without any intergeneration in the code to log web service messages.

In the following configuration web service messages will be logged to console on INFO level.

log4j.rootLogger=WARN, console
 
## Output cxf logging information to console
log4j.logger.org.apache.cxf.interceptor.LoggingInInterceptor=INFO, console
log4j.logger.org.apache.cxf.interceptor.LoggingOutInterceptor=INFO, console
 
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%6p | %d | %F | %M | %L | %m%n

More information related to logging and debuging in Apache CXF can be found here.