« Archives in February, 2010

*nix commands I can’t do without

Unix/Linux/*nix survival 101

Let me start with the obvious: I’m definitely not a unix guru by any means. I do however use it on a daily basis for basic build/development oriented tasks, so I know enough to get by. Since my friend just installed his first ever linux distribution (CentOS, Huzzah!), I thought I’d write something up on some common unix commands that help me get through the day.

grep [command flags] [search text] [filename]

grep (global | regular expression | print) is the file text search command. Give it a regular expression and it will print out what it finds in the file indicated by filename. Here’s an example:

[root@bedrock some_jboss_folder]$ grep html readme.html
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html><head>
<meta content=”text/html” http-equiv=”content-type”>
<a href=”http://docs.jboss.org/html”>here</a>.</li>
<li><a href=”http://www.jboss.org/index.html?module=bb”>JBoss
Server  is licensed under the <a href=”lgpl.html”>LGPL</a>,
</body></html>

Some useful flags include -R (recurse into sub directories), -c (show just the total match count), -m NUM (return the NUM number of results), and -i (ignore upper/lower case).

ps aux | grep [search text]

This is a command you can use to get information about what processes the kernel is currently running. Adding the pipe after the ps command feeds the listing results to the grep search command. This is particularly useful when you want to look for a specific set of procs run by a user or script. Here’s an example:

[root@bedrock ~]$ ps aux | grep jboss
jboss 10910 0.0 0.1 4884 1176 ? S Feb04 0:00 /bin/sh /server/jboss/bin/run.sh -c services -b 192.168.1.253 -Djava.net.preferIPv4Stack=true
jboss 10932 0.2 36.4 1089728 371456 ? Sl Feb04 31:43 java -Dprogram.name=run.sh -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djava.net.preferIPv4Stack=true -Djava.endorsed.dirs=/server/jboss/lib/endorsed -classpath /server/jboss/bin/run.jar org.jboss.Main -c services -b 192.168.1.253 -Djava.net.preferIPv4Stack=true
500 20300 0.0 0.0 4200 700 pts/0 S+ 20:43 0:00 grep jboss

ps (process status) fetches a list of running pocsses. ax flags the command to return a listing of all procs. u flags to also list the user that the proc is running as. I use the grep to figure out if a jboss server is up and running, and sometimes to see what input parameters it used on startup – like what ip it bound to : “-b 192.168.1.253”. The results above lists first the user and process id, and then information about the proc.

netstat -ntalp | grep [search text]

This command must be run as root, but it lets you get a listing of network ports that are currently in use. This is particularly useful when trying to figure out port conflicts or to see if a particular server is listening on the correct port.

[root@bedrock ~]# netstat -ntalp | grep java
tcp 0 0 192.168.1.253:8009 0.0.0.0:* LISTEN 10932/java
tcp 0 0 192.168.1.253:4713 0.0.0.0:* LISTEN 10932/java
tcp 0 0 192.168.1.253:4457 0.0.0.0:* LISTEN 10932/java
tcp 0 0 192.168.1.253:1098 0.0.0.0:* LISTEN 10932/java
tcp 0 0 192.168.1.253:1099 0.0.0.0:* LISTEN 10932/java
tcp 0 0 192.168.1.253:8080 0.0.0.0:* LISTEN 10932/java

You can grep for port, ip/domain, status etc.

kill [signal flag] [process id]

This is the standard “kill process”, “terminate it dead” command. Usually when a proc refuses to shut down and all hell is breaking loose, and you can’t take no for an answer, signal flag “-9” will insta kill the proc. You can get the process id from the “ps aux | grep” command.

root@bedrock jboss]$ kill -9 10932

Here I took the process id from the jboss script that was running from the ps aux | grep command example listed above. Use ps aux to figure out which process id you want to terminate.

./run.sh [args]

This is the standard syntax for invoking a script, assuming you have run privileges. In windows you’d just type in the name of the script, but in unix you should prefix the script name with “./”.

As Dave Cheney explains in a comment:

    The reason you have to put “./” as a prefix to a script in your current working directory is the search path for executable programs does not (generally) include “.”
    To the shell, “.” expands to the current directory so ./run.sh is equivalent to /home/kevin/run.sh (for example). As you have provided a full absolute path, the shell will not have to try the prefixes available in your $PATH environment.

So essentially, by adding the “./” before the script name you feed the shell a fully qualified executable path to the script you want to run, that way it doesn’t have to guess where your script is. So if the script is named run.sh and your current working directory is in a folder named bin, you can invoke it like this:

root@bedrock bin]$ run.sh -c services -b 192.168.1.253 -Djava.net.preferIPv4Stack=true

If your script takes parameters, you can pass them into the script after the script name.

tail [-f or -NUM] [path to file]

tail is a command that outputs the contents of a file to the terminal window. If you use the “-f” flag, it’ll continuously read the file as its contents grows. If you feed it a line count like “-1000” it will output the 1000 most recent line entries of the file. We’ll say something like – “Hey, I’m gonna tail the logs while the server starts up”. This means we’re monitoring the logs using this tail command. And knowing is half the battle.

Musk explains a better alternative that allow you to drop out of follow and search:

    You do not need tail use less +F or press Shift-F while in less and it will follow the currently choosen file if content is added.

    Example: log.txt

    less +F log.txt and you will have the same behaviour as when using tail -f log.txt except that you can use CTRL+C to drop out of follow mode and then use the search features available in less.

chown -R [group].[user]

This changes a file or directory’s owners to a new group/owner. The -R flag tell is to recurse the command into sub directories.

root@bedrock jboss]$ chown -R jboss.jboss

This command will work assuming there is a group and user named jboss, and it will change all files and folders in the current directory and lower to jboss.

chmod -R [permissions] [filename/expression]

This will set the permissions for the implied files to the new set of permissions listed. The mode can be indicated as either a string explanation of what each group can do or a 4 octal digit equivalent number.

[root@bedrock some_jboss_folder $ chmod ug=rwx,o=rw readme.html
[root@bedrock some_jboss_folder $ chmod 0775 readme.html

In the first example, we set the file owner (u) and group (g) to allow read (r), write (w) and execute (x). Then we set everyone else’s (o) permissions to read and write only, no execute. In the second example, we set it to 0775, which is the octal digit representation of the first command. 0777 will set read/write/exectue permissions allowed to everyone, its the same as ugo=rwx.

vi [filename]

Basic text editor *nix usually ships with. It will open up the indicated file in read mode, and if it doesn’t exist will let you create a new text file without saving to disk. To enter editor mode, hit the Insert key, you can then edit the file. After you make your edits, hit the Escape key to get into command line mode. If you want to save the file, enter “:w”. If you then want to quit, type in “:q”.

[root@bedrock some_jboss_folder ]$ vi readme.txt
<ul>
<li>lib/ – the same
static library jars with a few jars, as most have moved to top level common/lib</li>
</ul≶
:w
“readme.txtl” 718L, 36365C written

ping -c [ip/domain]

Pings an ip or domain with a packet of data. Unlike the windows cousin, you have to either pass in the number of times to ping (-c NUM) or hit control+c to stop pinging.

[root@bedrock some_jboss_folder ]$ ping -c 4 localhost
PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=64 time=0.040 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=3 ttl=64 time=0.033 ms
64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=4 ttl=64 time=0.048 ms

— localhost.localdomain ping statistics —
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.033/0.041/0.048/0.009 ms

top

This command takes over your terminal window and fills it with a listing of all the procs that are currently running, along with instruction crunching information. Hitting the < and > will scroll you through the results. q will quit top, returning you to the linux prompt. This is what it looks like:

top – 23:12:30 up 40 days, 16:38, 1 user, load average: 0.06, 0.02, 0.00
Tasks: 158 total, 1 running, 121 sleeping, 36 stopped, 0 zombie
Cpu(s): 0.0%us, 0.2%sy, 0.0%ni, 99.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1018232k total, 1003040k used, 15192k free, 138436k buffers
Swap: 2064376k total, 30236k used, 2034140k free, 312912k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2165 smmsp 20 0 9208 748 640 S 0.0 0.1 0:00.40 sendmail
1359 rpcuser 20 0 2988 560 556 S 0.0 0.1 0:00.03 rpc.statd
1346 rpc 20 0 2404 556 504 S 0.0 0.1 0:02.62 rpcbind
1 root 20 0 2012 624 560 S 0.0 0.1 0:04.71 init

man [command name]

If you need more detail on a specific command, you can get help from the unix manual by invoking man:

[root@bedrock ~]# man top
TOP(1) Linux Userâs Manual TOP(1)

NAME
top – display Linux tasks

SYNOPSIS
top -hv | -bcHisS -d delay -n iterations -p pid [, pid …]

The traditional switches â-â and whitespace are optional.

DESCRIPTION
The top program provides a dynamic real-time view of a running system. It can display system summary informa-
tion as well as a list of tasks currently being managed by the Linux kernel. The types of system summary
information shown and the types, order and size of information displayed for tasks are all user configurable
and that configuration can be made persistent across restarts.

ls [list flag] [path to directory]

This prints out a listing of the indicted directory’s contents, or the current directory if no path is supplied. -l lists one file/directory per line of output, and -a lists everything including files that start with a period.

[root@bedrock ~]# ls -la
total 168
drwxr-x—. 10 root root 4096 2009-11-20 23:09 .
drwxr-xr-x. 30 root root 4096 2010-02-07 22:32 ..
-rw——-. 1 root root 1675 2009-11-11 18:55 anaconda-ks.cfg
-rw——-. 1 root root 21354 2010-02-10 03:39 .bash_history
-rw-r–r–. 1 root root 18 2009-03-30 07:51 .bash_logout
-rw-r–r–. 1 root root 176 2009-03-30 07:51 .bash_profile
-rw-r–r–. 1 root root 176 2004-09-22 23:59 .bashrc
drwx——. 3 root root 4096 2009-11-12 02:17 .config
-rw-r–r–. 1 root root 100 2004-09-22 23:59 .cshrc
drwx——. 3 root root 4096 2009-11-11 19:06 .dbus

cat [filename1] [filename2] > [outputfile]

cat lets you concatenate and output the contents of a file of multiple files to the terminal window, or write it to a file if you include the “>” operator. Thanks Kevin. Here’s an example:

tests.txt

[root@bedrock ~]# vi test.txt
concatenate me!
this is a test

concatenate.txt

[root@bedrock ~]# vi concatenate.txt
a file that needs to be concatenated

again

output.txt

[root@bedrock ~]# cat test.txt concatenate.txt > output.txt

The result

[root@bedrock ~]# more output.txt
concatenate me!
this is a test
a file that needs to be concatenated

again

sed -i ’s/[some_text/other_text]/’ [filename]/

sed – stream editor for filtering and transforming text (blatantly stolen from “man sed”‘s documentation). This command will replace “some_text” with “other_text” in the file indicated. One occurrence per line is replaced. Thanks for this one Silvery.

Consider the file “test.txt”:

[root@bedrock jboss]# more test.txt
this is a file
this ia another file
lets faceroll files
ok

And this is what happens when we run sed on it:

[root@bedrock jboss]# sed -i ‘s/file/folder/’ test.txt
[root@bedrock jboss]# more test.txt
this is a folder
this ia another folder
lets faceroll folders
ok
[root@bedrock jboss]#

more/less

more/less – enables you to view the contents of a file within a page on the screen. Once you are browsing the contents, you can hit “s” or “f” to scroll multiple lines of text. “v” will fire up an editor at the current line you’re working on. If you have a large list of files and want to check them one page at a time, you could try “ls | less”. Thanks again Kevin.

clear

Clears the visible screen of text, starting your prompt at the top of the window.

mkdir [directory name]

This command simply creates a directory with default permissions and ownership.

cp -R [source] [destination directory]

Copies a file/folder from one location into another. -R flags to copy recursively.

mv [source] [destination directory]

Renames a source directory or folder to a new location/name.

rm -Rf [folder/file]

Deletes a file. -R flags to delete recursively. When invoked on a directory it would normally go line by line asking you if you want to delete such-and-such file, use the “f” flag to force delete and skip the file by file questions.

cd [path to new directory]

cd changes the current directory to the path indicated. A “..” means to move up one directory. If the path begins with “/” it means start from the disk root folder. Anything else implies a relative path to the new folder.

– -color=auto

In his comment, Ryan Fox points out:

    The `- -color=auto` option adds colour to the output of some commands, like ls or grep. In ls, the colours change depending on the file type, permissions, etc. In grep, it will highlight the text that matched your regex.

Here’s an example:

[root@bedrock jboss]# ps aux | grep jboss – -color=auto
root 5215 0.0 0.0 4200 712 pts/1 S+ 05:56 0:00 grep jboss –color=auto
jboss 10910 0.0 0.1 4884 1176 ? S Feb04 0:00 /bin/sh /server/jboss/bin/run.sh -c services -b 192.168.1.253

Open ended

I’m sure there must be other useful commands I have missed. If anyone has any other suggestions to add/edit these entries, please feel free to comment and I’ll update accordingly.

Transforming XML into MS Excel XML

MS Excel understands XML?

If you need to export xml to a Microsoft Excel friendly format, you could stress over the HSSF (Horrible Spread Sheet Format, for the uninitiated) format with apache’s POI framework or you could transform your xml into an format Excel understands. This approach will allow you to decorate your cells with stylized fonts and borders; what it will not allow you to do is create or add complex objects like charts, graphs or pictures. This xml format is a watered down version of excel. If you require the ability to embed images, graphs and complex objects, have a look at Apache’s framework.

Alright, Show me some code

Let’s take a look at the xml we’re going to be using:

<Report caption="Reporting">
	<block 	caption="Staff Memeber Report" 
		userIdLabel="User Id" 
		accountNameLabel="Account Name"
		createDateLabel="Date Created"
		emailLabel="Email">

		<staffMember id="00000" 
			accountName="accountName1"
			createDate="2009-01-02" 
			accountEmail="someone1@domain.com"/>
		<staffMember id="00001"
			accountName="accountName2"
			createDate="2009-02-17" 
			accountEmail="someone2@domain.com"/>
		<staffMember id="00002"
			accountName="accountName3"
			createDate="2009-03-14" 
			accountEmail="someone3@domain.com"/>

	</block>
</Report>

Pretty Straight forward xml, optimized for shorter xpath expressions.

The Magic XSL

<?xml version="1.0" encoding="ISO-8859-1"?>
<?mso-application progid="Excel.Sheet"?>
<xsl:stylesheet version="1.0" 
	xmlns:html="http://www.w3.org/TR/REC-html40"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns="urn:schemas-microsoft-com:office:spreadsheet"
	xmlns:o="urn:schemas-microsoft-com:office:office" 
	xmlns:x="urn:schemas-microsoft-com:office:excel"
	xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">

	<xsl:template match="/">

		<Workbook>
			<Styles>
				<Style ss:ID="Default" ss:Name="Normal">
					<Alignment ss:Vertical="Bottom" />
					<Borders />
					<Font />
					<Interior />
					<NumberFormat />
					<Protection />
				</Style>
				<Style ss:ID="s21">
					<Font ss:Size="22" ss:Bold="1" />
				</Style>
				<Style ss:ID="s22">
					<Font ss:Size="14" ss:Bold="1" />
				</Style>
				<Style ss:ID="s23">
					<Font ss:Size="12" ss:Bold="1" />
				</Style>
				<Style ss:ID="s24">
					<Font ss:Size="10" ss:Bold="1" />
				</Style>
			</Styles>

			<Worksheet ss:Name="{//Report/@caption}">
				<Table>
					<Column ss:AutoFitWidth="0" ss:Width="85" />
					<Column ss:AutoFitWidth="0" ss:Width="115" />
					<Column ss:AutoFitWidth="0" ss:Width="115" />
					<Column ss:AutoFitWidth="0" ss:Width="160" />
					<Column ss:AutoFitWidth="0" ss:Width="115" />
					<Column ss:AutoFitWidth="0" ss:Width="85" />
					<Column ss:AutoFitWidth="0" ss:Width="85" />
					<Column ss:AutoFitWidth="0" ss:Width="160" />

					<Row ss:AutoFitHeight="0" ss:Height="27.75">
						<Cell ss:StyleID="s21">
							<Data ss:Type="String">Example Spreadsheet</Data>
						</Cell>
					</Row>
					<Row ss:AutoFitHeight="0" ss:Height="18">
						<Cell ss:StyleID="s22">
							<Data ss:Type="String">
								<xsl:value-of select="//Report/@caption" />
							</Data>
						</Cell>
					</Row>
					<Row>
						<Cell>
							<Data ss:Type="String">
							</Data>
						</Cell>
					</Row>

					<xsl:call-template name="staffReport" />


				</Table>
			</Worksheet>

		</Workbook>

	</xsl:template>


	<xsl:template name="staffReport">

		<Row ss:AutoFitHeight="0" ss:Height="18">
			<Cell ss:StyleID="s23">
				<Data ss:Type="String">
					<xsl:value-of select="//Report/block/@caption" />
				</Data>
			</Cell>
		</Row>
		<Row>
			<Cell ss:StyleID="s24">
				<Data ss:Type="String">
					<xsl:value-of select="//Report/block/@userIdLabel" />
				</Data>
			</Cell>
			<Cell ss:StyleID="s24">
				<Data ss:Type="String">
					<xsl:value-of select="//Report/block/@accountNameLabel" />
				</Data>
			</Cell>
			<Cell ss:StyleID="s24">
				<Data ss:Type="String">
					<xsl:value-of select="//Report/block/@createDateLabel" />
				</Data>
			</Cell>
			<Cell ss:StyleID="s24">
				<Data ss:Type="String">
					<xsl:value-of select="//Report/block/@emailLabel" />
				</Data>
			</Cell>
		</Row>

		<xsl:for-each select="//Report/block/staffMember">

			<Row>
				<Cell>
					<Data ss:Type="String">
						<xsl:value-of select="@id" />
					</Data>
				</Cell>
				<Cell>
					<Data ss:Type="String">
						<xsl:value-of select="@accountName" />
					</Data>
				</Cell>
				<Cell>
					<Data ss:Type="String">
						<xsl:value-of select="@createDate" />
					</Data>
				</Cell>
				<Cell>
					<Data ss:Type="String">
						<xsl:value-of select="@accountEmail" />
					</Data>
				</Cell>
			</Row>

		</xsl:for-each>
	</xsl:template>

</xsl:stylesheet>

The overall XSL structure is pretty much the same as any other XSL. I broke up the report into two main components: the generic, enclosing, Workbook xsl, and the main staffMember xsl template. The enclosing Workbook xsl has the report metadata and sets up the overall layout while the staffMember template loops through the staffMember xml nodes, outputting one row of data per node.

Styled Text

Let’s take a look at the styles mechanism:

<Styles>
	<Style ss:ID="Default" ss:Name="Normal">
		<Alignment ss:Vertical="Bottom" />
		<Borders />
		<Font />
		<Interior />
		<NumberFormat />
		<Protection />
	</Style>
	<Style ss:ID="s21">
		<Font ss:Size="22" ss:Bold="1" />
	</Style>
	...
</Styles>

Notice there is a “Defualt” style, which offers a venue to lay out default styles for all your cells. Then you have unique style definitions like ss:ID=”s21″ which define a font size and weight:

<Font ss:Size="22" ss:Bold="1" />

Size is measured in Points, so take that into account as you determine the size you would like to use. The Bold=”1″ flags the style to render as Bold weight, as oppose to regular, non bold which would be Bold=”0″. If you wanted to change the font you could add ss:FontName=”Tahoma”. A particular style is linked to a cell by adding the style ID as a cell attribute like this:

<Cell ss:StyleID="s22">
	<Data ss:Type="String">some stylized text</Data>
</Cell>

where the ss:StyleID matches the style definition’s ss:ID.

Sizing Columns

Note that you can add multiple Worksheets – all you need to do is add more Worksheet XML nodes, and stick data in them. You can initialize the starting column widths by using the Column nodes under the Table node:

<Column ss:AutoFitWidth="0" ss:Width="85" />
<Column ss:AutoFitWidth="0" ss:Width="115" />

If AutoFitWidth is set to true, it will auto size the columns to whatever appropriate width the numeric or date values consume. Text is not automagically resized. When it’s flagged to 0, and a Width is specified, it will resize to whatever Width is set to. When set to true (1), and a Width is present it will set the width to the specified value, and auto size if the cell data is larger than the Width.

Simple Formulas

You can also embed Excel formulas as part of the XSL so your spreadsheet can come pre-wired with formulas. I didnt include any in this example but I’ll go over an example snippet of code:

<Cell ss:Index="2" ss:Formula="=SUM(R[-3]C,R[-2]C,R[-1]C)">
	<Data ss:Type="Number"></Data>
</Cell>

ss:Formula=”=SUM(R[-3]C,R[-2]C,R[-1]C)” might look a little strange, since you’re probably used to the =SUM(A12,A13,A14) type of notation used from the nomal gui. The XML notation is merely a mechanism for locating which cells to add up in this particular sum. R corresponds to the relative row, and C corresponds to the relative column. So, R[-3] means the row 3 spaces above the current cell, and C means the current cell (since there is no “[x]” notation). If we wanted to include the cell 2 rows down, and 4 columns to the left we could express that as R[2]C[-4]. Simple x/y coordinates. For more on formulas, have a closer look at Microsoft’s ss:Cell documentation.

The Rendered Spreadsheet

That’s pretty much all there is to it. The xml isn’t perfect, but its definitely more presentable than regular csv files without getting in the way for anyone that needs to work with the actual data. Here’s a screen shot for the aetheists:

xml rendered for excel

XML rendered as MS Excel output via xslt

Source Files
report.xml
report.xsl
rendered.xml (change extension to .xml, and open with MS Excel)

Resources
Microsoft overview on Excel XML structure
Microsoft XML Node reference
Wikipedia Article on Office XML formats. Yep Word also has an XML format.

Sidenote:

When looking at the MS Excel documentation be aware that they didn’t declare:

xmlns="urn:schemas-microsoft-com:office:spreadsheet"

but instead

xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"

So their Workbook xsl has ss: preceding every node, when compared to my workbook xsl.

Integrating Spring MVC 3.0 with JSR 303 (aka javax.validation.*)

Annotated POJO validation comes to a JDK near you!

The new annotated validation spec (jsr 303) is pretty slick, especially when used along side Spring MVC 3.0, and when backed by ejb3 entities. I’m pretty impressed with how easily it integrates with Spring MVC’s framework, and with how seamlessly error messages are passed to the form taglibs so they show up in your web forms.

I know some of you might argue that the current validation framework might not address complex validations, but after giving Hibernate’s reference implementation documentation a look, it seems interdependent validations are at least possible through embedded @Valid in complex objects. Even if you have to come up with your own really weird validation for a particular field, jsr 303/hibernate offers a way to create your own custom annotation driven validations. For the remaining 95% of all the other web forms, you’re probably going to be alright if you use the pre-defined validations offered by jsr 303.

Getting started

Download the jsr 303 reference implementation jars from SourceForge, via Hibernate’s download page. You’ll need to add the main, Hibernate validator jar (currently hibernate-validator-4.0.2.GA.jar as of 2/8/2009) and the included jars in the release jar’s lib directory to your application’s classpath if they’re not already there (if you’re on jboss 5.1, probably at least validation-api-1.0.0.GA.jar, maybe more). The Hibernate reference implementation release also includes the jar files required to run in a jdk 5 runtime, include those if you’re not running on jdk 6. Download Spring MVC from Spring’s download page, its part of the Spring 3.0 release. Spring MVC requires the following jars in your classpath:

    • org.springframework.asm
    • org.springframework.beans
    • org.springframework.context
    • org.springframework.context-support
    • org.springframework.core
    • org.springframework.expression
    • org.springframework.web
    • org.springframework.web.servlet

Wiring Spring MVC

You’ll need to make sure you map Spring MVC correctly. Consider the following in web.xml:

	<!-- Spring Action Servlet -->
	<servlet>
		<servlet-name>spring</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				/WEB-INF/spring-servlet.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>spring</servlet-name>
		<url-pattern>*.sf</url-pattern>
	</servlet-mapping>

And then in spring-servlet.xml:

<?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:context="http://www.springframework.org/schema/context">
		
	<!-- Scans the class path of this application for @Components to deploy -->
	<context:component-scan base-package="com.faceroller.web" />
	
	<context:annotation-config/>

	<bean id="multipartResolver" 
	class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

	<!-- flags annotations for processing -->
	<mvc:annotation-driven />

	<!-- forward "/" requests -->
	<mvc:view-controller path="/" view-name="welcome"/>

	<!-- Configures Handler Interceptors -->	
	<mvc:interceptors>
	<!-- Changes the locale when a 'locale' request parameter is sent -->
	<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
	</mvc:interceptors>

	<!-- Saves a locale change using a cookie -->
	<bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" 
		id="localeResolver" />

	<!-- hey man, I like my jsp files in "/". WEB-INF just seems.. ugly -->
	<bean 
	  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	  <property name="viewClass" 
			value="org.springframework.web.servlet.view.JstlView"/>
	  <property name="prefix" value="/"/>
	</bean>
	
	<bean 
	  class="org.springframework.context.support.ResourceBundleMessageSource"
	  id="messageSource">  
		<property name="basename" value="messages" />
	</bean>  
	
</beans>

Now that we’ve squared away the setup, on with the examples:

Example ejb3 jsr-303 validation equipped entity bean

import javax.persistence.*;
import javax.validation.Valid;

@Entity
@Table(name="tb_inventory")
public class InventoryItem implements Serializable {

	private static final long serialVersionUID = 1L;
	
	@Id  
	@GeneratedValue(strategy=GenerationType.IDENTITY) 
	protected int id;
	
	@NotNull
	protected BigDecimal price = new BigDecimal("0.00");	
	
	@NotEmpty(message = "Name is a required field")
	protected String name;
	
	@Min(100)
	protected int minimumPrice;

	@Email
	private String mail;

	@Pattern(regexp="[a-z]+")
	private String lowerCaseName;
	
	@Future
	private Date futureDate;

	@AssertTrue
	private boolean mustBeTrue;

	@OneToMany
	@JoinTable(name="tb_order_items_to_images")
	@Valid
	protected List<InventoryImage> images = new ArrayList<InventoryImage>();
	
	
	// setters/getters here...
}

Lets examine the annotations:

@NotNull

@NotNull flags the annotated field as valid only if it has a value assigned. A String with a null value will fail, while a String with a “” value will pass. Since the “message” parameter is not defined, the error message will default to whatever the validation package ships with. In this case, I think the message will read “name is a required field”.

@NotEmpty(message = “Name is a required field”)

@NotEmpty flags the annotated field as valid if the field is both not null and not a value of “”. Since the “message” parameter is defined for this annotation, the param value will replace the default message passed into spring mvc’s error framework.

@Min(100)

@Min flags the field as valid only if it has a value equal to or higher than the value in the parens. The contrary to this is @Max, which will flag as valid values lower than the value in the parens.

@Email

@Email flags the field as valid only if the field is a valid email.

@Pattern(regexp=”[a-z]+”)

@Pattern will flag the field as valid only if the string matches the regular expression passed in as the parameter. In this case it will only pass if the string is made up only of lowercase letters.

@Future

@Future will flag as valid only if the date annotated is in the future. The contrary to this is @Past, which would be valid only if the date has already passed.

@AssertTrue

@AssertTrue will flag as valid if the annotated boolean resolves to true. The contrary to this is @AssertFalse, which will flag as valid only if the boolean resolves to false.

@Valid

@Valid will validate only if the complex object annotated validates as true. Lets say in this case that InventoryImage has two validation annotated fields; if any InventoryImage fails either of those two fields, then the enclosing InventoryItem will fail validation because of the @Valid annotation. This is how compelx cross object validations are supported, other than defining your own.

Now that we’ve annotated our bean, we’ll need to hook it into a Spring MVC controller.

The Spring MVC Controller

package com.faceroller.web;

@Controller
@RequestMapping("/inventory")
public class InventoryController {

	private static Log log = LogFactory.getLog(InventoryController.class);
	
	/**
	 * initialize the form
	 *
	 */
	@RequestMapping("/add/setup.go")
	public ModelAndView addInventorySetup(InventoryItem item){
		
		log.info("setup add inventory");
		return new ModelAndView("/inventory/add.jsp", "item", item);
	}

	/**
	 * process the form
	 *
	 */
	@RequestMapping(value="/add/meta.go", method=RequestMethod.POST)
	public String processInventoryMeta(
			@ModelAttribute("item") @Valid InventoryItem item, 
			BindingResult result) {
		
		log.info("process add inventory");
		
		if (result.hasErrors()) {
			return "/inventory/add.jsp";
		}

		InventoryService service = ServiceLocator.getInventoryService();
		service.addInventoryItem(item);
		
		return "redirect:/add/images/"+item.getId();
	}
	
	/**
	 * forward to whatever page you want
	 *
	 */	
	@RequestMapping("/browse/item/{itemId}")
	public ModelAndView getInventoryItem(@PathVariable int itemId){

		log.info("getting item");

		InventoryService service = ServiceLocator.getInventoryService();
		InventoryItem item = service.getInventoryItemById(itemId);

		return new ModelAndView("/inventory/browse.item.jsp", "item", item);
	}
	
}

Pay special attention to

	@RequestMapping(value = "/add/meta.go", method=RequestMethod.POST)
	public String processInventoryMeta(
			@ModelAttribute("item") @Valid InventoryItem item, 
			BindingResult result) 

You’ll notice @Valid marked up right before the InventoryItem item bean parameter. This is the annotation that does all the validation magic for us. There is no need to implement a custom validator factory, as spring mvc’s framework would normally require. If the bean fails validation, BindingResult result will be prepopulated with all corresponding JSR 303 validation errors. The catch is you have to add the @ModelAttribute(“item”) annotation to the signature, otherwise the form bean in the jsp will not have access to all the error messages passed along by the validations.

The jsp code

<form:form method="post" commandName="item" action="/process/form">
<table width="100%" border="0">
	<tr><td colspan="3" class="bottomPadding">
		<span class="secionHeader">Add item to inventory</span>
	</td></tr>
	<tr><td class="labelColumn" width="100">
		Price 
	</td><td width="100">
		<form:input path="price"/>
	</td><td>
		<form:errors path="price" cssClass="error"/>
	</td></tr>
	<tr><td class="labelColumn">
		Name
	</td><td>
		<form:input path="name"/>
	</td><td>
		<form:errors path="name" cssClass="error"/>
	</td></tr>
</table>
</form:form>

This is just a simple form, nothing new here, but I’m including for completeness. The Spring MVC framework will correctly populate the form tags with any bean errors should the form fail validation. The form tags are part of the standard spring taglibs, found in the org.springframework.web.servlet.* jar included in the Spring 3.0 distribution.

EDIT:
Stuart Gunter pointed out in a comment to this post that there is a workaround for injecting your own messages using spring’s autowiring. Click the jump for his example.

Resources
Hibernate 4.x Validation reference implementation
Spring MVC 3.0 documentation

Quartz Scheduled Jobs – v1.5.2

Java, XML, and cron driven scheduling made easy.

Projects here and there often need some kind of mechanism to schedule jobs at odd hours, or intervals. Quartz is a robust, flexible tool you can use to accomplish simple to complex job scheduling. There are a number of ways to use/configure quartz, but I’ve grown accustomed to using it with an xml based configuration. There are a few things we need to set up unfortunately, so there is a certain amount of plumbing we need to work out, but once that infrastructure is set up, its much less work to set up additional jobs.

web.xml

Originally, I went on about writing a custom quartz servlet to initialize the engine, but theres an even easier way to set this up as Sibz has pointed out in a comment:

<servlet>
	<servlet-name>
		QuartzInitializer
	</servlet-name>
	<display-name>
		Quartz Initializer Servlet
	</display-name>
	<servlet-class>
		org.quartz.ee.servlet.QuartzInitializerServlet
	</servlet-class>
	<load-on-startup>1</load-on-startup>
	<init-param>
		<param-name>config-file</param-name>
		<param-value>/some/path/my_quartz.properties</param-value>
	</init-param>
	<init-param>
		<param-name>shutdown-on-unload</param-name>
		<param-value>true</param-value>
	</init-param>
	<init-param>
		<param-name>start-scheduler-on-load</param-name>
		<param-value>true</param-value>
	</init-param>
</servlet>

This xml snippet was blatanlty hijacked from quartz’ documentation page. As you might have guessed, this xml configuration goes in your web.xml. No need to write your own initializer servlet, just plug and play.

We’ll need to add 2 property files. The one that fine tunes the engine in our example is quartz.properties..

quartz.properties

If you noticed in the web.xml (the init param named “config-file” is set to the path <param-value>/some/path/my_quartz.properties</param-value>), we load up a properties file that configures the quartz engine.

org.quartz.plugin.jobInitializer.class=org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.fileNames = quartz-config.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs = true
org.quartz.plugin.jobInitializer.failOnFileNotFound =true

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool 
org.quartz.threadPool.threadCount = 5 
org.quartz.threadPool.threadPriority = 5

The first half of the settings is pretty straight forward, but the second half is all about tuning. Setting a class other than SimpleThreadPool means you’ve written your own implementation for quartz thread management. You probably really know what you’re doing and you can stop reading. Threadcount controls the number of quartz threads dedicated to the engine. One is plenty for a job that fires off once or a few times a day. If you plan on running thousands a day, with heavy loads you’ll want something like 50 threads and up towards about 100. Threadpriority 5 means normal priority, while priority 1 is highest priority. For the most part, 5 is plenty, if you have cpu intensive processing going on, you can tune this to make sure your jobs fire off when they’re supposed

The second file we need to set up is the xml that configures your quartz job…

quartz-config.xml

<quartz>
    <job>
        <job-detail>
            <name>scheduler</name>
            <group>schedulers</group>
            <description>schedule a nightly job</description>
            <job-class>com.examples.quartz.Scheduler</job-class>
            <volatility>false</volatility>
            <durability>false</durability>
            <recover>false</recover>
			<job-data-map>
				<entry>
					<key>username</key>
					<value>someUser</value>
				</entry>
				<entry>
					<key>password</key>
					<value>somePassword</value>
				</entry>
			</job-data-map>            
        </job-detail>
        <trigger>
            <cron>
                <name>scheduler-trigger</name>
                <group>scheduler-triggers</group>
                <job-name>scheduler</job-name>
                <job-group>schedulers</job-group>
                <cron-expression>0 0/5 * * * ?</cron-expression>
            </cron>
        </trigger>
    </job>
</quartz>

This file is made up of two main sections. Job-Detail configures the job’s metadata, while trigger defines the configuration and cron expression that fires off the job. Stuff like the name, and mappings needed to configure the matching trigger, or the xml parser will complain. Parameters can be added in job-data-map and passed into the job-class for processing. Which brings us to the last item of business: THE JOB IMPLEMENTATION CLASS!!!

Scheduler.java

Scheduler is the job implementing class that defines the unit of work preformed by the quartz job. JobExecutionContext contains all the job metadata defined in the configuring xml, and the data map is the object that contains all the name/value pairs listed in the xml we just wrote up. Here’s the full class:

package com.examples.quartz;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class Scheduler implements Job {
    
	protected static final Log log = LogFactory.getLog(Scheduler.class);

	public void execute(JobExecutionContext jobContext) 
		throws JobExecutionException {

		log.info("entering the quartz config");

		JobDataMap map = jobContext.getJobDetail().getJobDataMap();
		String username = (String) map.get("username");
		String password = (String) map.get("password");

		log.info("mapped data: " + username + "/" + password);
	}

}

.. And that’s all there is to setting up a quartz jobs. If we want to add additional quartz jobs, all we would need to do is add another job node in our quartz-config.xml and write another job interface implementing class. The rest pretty much stays the same, since all the heavy lifting has been done.

Ejb3 Basics: Deploying Message Driven Beans

Farewell to lazy auto queue generation in JBoss 5

MDB’s were never so easy to deploy and manage when ejb3 first came out. In Jboss 4, all you have to do was annotate a class with @MessageDriven, sprinkle some meta data here and there, stick it in the oven and wham! Instant “I cant believe I made an MDB!?!” In Jboss AS 5 however, MDB queues are no longer automatically created for your application anymore on boot. An inspection of the MDB llifecycle illustrates why:

  1. MDB deploys
  2. No existing Topic/Queue
  3. Topic/Queue is automatically created
  4. MDB is undeployed
  5. There’s no callback/hook to remove the created Topic/Queue. And if there was, should undeploying the MDB even be allowed to trigger this action?

blatantly stolen from JBAS-5114, 5th comment down – thanks Andy, and DeCoste by proxy

SO to reiterate… whereas JBoss AS 4.0 would have auto-created and MDB queues for you on boot, in 5.0 this no longer holds true. Consider the following MDB:

package com.examples.mdb;

import javax.ejb.*;
import javax.jms.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@MessageDriven(name = "MyQueue", activationConfig = {
        @ActivationConfigProperty(
        		propertyName = "destinationType", 
        		propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(
        		propertyName = "destination", 
        		propertyValue = "queue/MyQueue"),
        @ActivationConfigProperty(
        		propertyName="DLQMaxResent", 
        		propertyValue="1")
})
public class MyQueue implements MessageListener {
	
	private static final Log log = LogFactory.getLog(MyQueue.class);
	
	public void onMessage (Message msg) {
		try {
			
			log.debug("Processing MyQueue queue...");
			ObjectMessage oMsg = (ObjectMessage) msg;
			
			SomeObject result = (SomeObject ) oMsg.getObject();

			/**
			 * do stuff with the object
			 */

		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
}

In jboss 4 you could leave your MDB class like this, and the app server would automatically handle everything for you. If you plan on using jboss 5.+ however, you will have to choose one of the following..

Wire it yourself in destinations-service.xml

In /deploy/messaging/destinations-service.xml, you can add the MDB destination yourself, letting jboss know to create your queue on boot. Here’s an example configuration:

<?xml version="1.0" encoding="UTF-8"?>
<!--
	Messaging Destinations deployment descriptor.
 -->
<server>

	<mbean 
		code="org.jboss.jms.server.destination.QueueService"
		name="jboss.messaging.destination:service=Queue,name=MyQueue"
		xmbean-dd="xmdesc/Queue-xmbean.xml">
		<depends optional-attribute-name="ServerPeer">
			jboss.messaging:service=ServerPeer
		</depends>
		<depends>
			jboss.messaging:service=PostOffice
		</depends>      
	</mbean>

</server>

The only thing this configuration needs to change is the queue name – make sure it matches the name of the queue annotated in your MDB class. This by itself is the closest you can get to being lazy. You will need to make sure however that you add one destination for each of the MDB queues your application uses. Option two requires a little bit more work but you don’t have to muck around with the jboss environment…

Add deployment descriptors to auto create the queue via jboss.xml

You can instead deploy the optional jboss.xml file in your ejb jar file’s META-INF folder (in addition to your persistence.xml file if you’re using entities). Your ejb jar structure should then look like this:

ejb-jar.jar
	- / ejb classes and cool stuff here
	- / META-INF
		- MANIFEST.MF
		- persistence.xml
		- jboss.xml

And this is what jboss.xml would look like:

<?xml version="1.0" encoding="UTF-8"?>
<jboss xmlns="http://www.jboss.com/xml/ns/javaee" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee 
                           http://www.jboss.org/j2ee/schema/jboss_5_0.xsd" 
       version="3.0"> 
	<enterprise-beans>
		<message-driven>
			<ejb-name>MyQueue</ejb-name>
			<destination-jndi-name>queue/MyQueue</destination-jndi-name>
			<create-destination>true</create-destination>
		</message-driven>
	</enterprise-beans>
</jboss>

The key command in this file here being: <create-destination>true</create-destination>. This will flag jboss to create the queue for you if it doesn’t already exist. This approach would probably be better suited for jboss only deployments since the flag to auto create the queue is configured within a jboss exclusive deployment descriptor – jboss.xml.

Once either of these has been implemented, your MDB should be deployed, initialized and ready to fire up. Oh, and fist pumps to ALR for pointing me in the right direction – cheers buddy!