Monthly Archives: July 2008

Visio figures in LaTeX

This is one way to use figures made in Microsoft Visio in your latex (pdfLatex) document.

The first step is to get the figure as a PDF file. If you are using Visio 2007 you may use the PDF add-in from Microsoft. Another option is using Adobe Acrobat or the free PDFCreator.

When printing, select the figure and in the print dialog select the option to only print the current selection.

The problem is that the figures will use a whole page even if they’re small. You may either crop it (using a tool like pdfcrop) or specify a viewport when including the figure in the document.

To find out the viewport variables, convert the PDF to PostScript using pdf2ps. Now check the beginning of the file for a line like this:

%%BoundingBox: 56 368 446 551

This is the viewport variables to use when including the figure in the latex document:

\includegraphics[viewport = 56 368 446 551]{figure.pdf}

Or include it in a figure with caption that may be referenced:

\begin{figure}
	\begin{center}
		\includegraphics[viewport = 56 368 446 551]{figure.pdf}
	\end{center}
	\caption{Figure caption here}
	\label{myfigure}
\end{figure}

It may be referenced to in the text using e.g. Please see figure ~\ref{figure} for details. The tilde is used as a non-breaking space to avoid unfortunate linebreaks.

See this page for more details working with figures in Latex.

Installing GlassFish on Debian Etch or Ubuntu

I had to install GlassFish on an Debian Etch machine and here is how I did it (the purpose of these instructions is as a reminder to myself so I know what I did in case I have to do it again).

Install Java 5

First thing needed is Java 5. To be able to get Java 5 and other stuff, add contrib and non-free to each repository in /etc/apt/sources.list .

It should look something like this:

deb http://security.debian.org/ etch/updates main contrib non-free

deb http://ftp.debian.org/debian etch main contrib non-free
deb-src http://ftp.debian.org/debian etch main contrib non-free

Then simply run:
apt-get install sun-java5-jdk

Download GlassFish

Check the GlassFish website for the latest version and download it (URL may be different depending on version):

wget http://java.net/download/javaee5/v2ur2/promoted/Linux/glassfish-installer-v2ur2-b04-linux.jar

Install GlassFish

Install GlassFish by running:
java -jar -mx256M glassfish-installer-v2-b09.jar

For convenience it might be nice to move GlassFish to a version independent directory name and make symlink (will make future upgrades easier as well):

mv glassfish /opt/glassfish-v2ur2-b09
ln -s /opt/glassfish-v2ur2-b09 /opt/glassfish

Now setup GlassFish:

cd /opt/glassfish
/opt/glassfish/lib/ant/bin/ant -f setup.xml

If you get an permission error, make sure ANT is executable (note that this is just a standard ANT, if you already have ANT you may use that one instead):

chmod u+x /opt/glassfish/lib/ant/bin/ant

Start the application server by running:

/opt/glassfish/bin/asadmin start-domain

Verify that you may reach http://localhost:8080 and http://localhost:4848 (replace localhost if server is somewhere else).

Finally it might be a good idea to change the default admin password:

/opt/glassfish/bin/asadmin change-admin-password --user admin

Create init script

Based on the /etc/init.d/skeleton I created the following init-script:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          glassfish
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: glassfish initscript
# Description:       Simple initscript for GlassFish App server
### END INIT INFO

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/opt/glassfish/bin
DESC="GlassFish Java EE5 App server"
NAME=glassfish
ASADMIN=asadmin
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
        $ASADMIN start-domain \
                || return 1
}

#
# Function that stops the daemon/service
#
do_stop()
{
        $ASADMIN stop-domain \
                || return 1
}

case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        sleep 10
        case "$?" in
          0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 3
        ;;
esac

:

Save it as glassfish, then run:

cd /etc/init.d
update-rc.d glassfish defaults

Set executable permission on init script with chmod a+x glassfish .

That’s it!

These instructions are very much based on similar posts by Jasper Kalkers Installing Glassfish 2 on ubuntu 7.10 and Cay Horstmann Installing GlassFish and PostgreSQL on Ubuntu Server Edition.

Enable symbolic links in GlassFish

To enable symbolic links in GlassFish, which is disabled by default, go to the admin interface, click Configuration > Http Service > Virtual Servers and then the name of of the virtual server you are using (e.g. server).

Under Additional Properties, click Add Property and enter allowLinking as name and true as value.

It is also possible to activate symbolic links using sun-web.xml.

Error deploying AppFuse application on Tomcat

When trying to deploy an AppFuse application on Tomcat I received the following error:

org.apache.jasper.JasperException: Unable to compile class for JSP:

An error occurred at line: 153 in the generated java file
Type mismatch: cannot convert from null to int

An error occurred at line: 168 in the generated java file
Cannot cast from Object to int

The source of the error turned out to be due to the Constants.java file containing a variable that was not a String. Changing it into a string (and add appropriate type-casting in the application) got rid of the error.

Date fields in forms using Spring and AppFuse

I had some problems getting date fields to work (and return a friendly error message) so here comes a little documentation for future reference. This was in an AppFuse based Spring Framework project.

The model contains a java.util.Date property and simply exposing it as usual in a form will cause an exception since Spring doesn’t know how to convert the string into a Date:

Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property startTime; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property startTime: no matching editors or conversion strategy found

To solve this we need a custom property editor. It may be registered by overriding the initBinder() method of a controller. Spring already contains a CustomDateEditor that we may use for this purpose.

protected void initBinder(HttpServletRequest request, 
                          ServletRequestDataBinder binder) {
    SimpleDateFormat dateFormat =
        new SimpleDateFormat(getText("date.format", request.getLocale()));
    dateFormat.setLenient(false);
    binder.registerCustomEditor(Date.class, null, new CustomDateEditor(dateFormat, true));
}

Note that you may replace the getText() call with a hard-coded “yyyy-MM-dd” or similar, at least for debugging purposes.

If it is an AppFuse project and the controller extends BaseFormController then you don’t need this since the CustomDateEditor is already registered in the BaseFormController.initBinder() method.

Now it should work, however, the error message isn’t especially user-friendly when entering an invalid date:

Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property startTime; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: “2008-37-09”

Better error messages may be provided using the resource file of the application (make sure you have a ResourceBundleMessageSource set up) by specifying typeMismatch error message for this type:

typeMismatch.java.util.Date={0} is an invalid date.

The {0} will be replaced by the property name, in this case startTime, which may not be desired. This may be overridden by setting a custom error message for this specific property:

typeMismatch.startTime=Start time is an invalid date.

Do also make sure to update validation.xml accordingly.

Hibernate HQL like query using named parameters

Using the LIKE condition with a “%” sign for pattern matching in a HQL query with named parameters required some tweaking.

This did not work:

String query = "from user u where u.name like %:name%"

getHibernateTemplate().findByNamedParam(query, "name", str);

It resulted in a org.hibernate.QueryException: unexpected char: ‘%’ error.

Next I tried using single quotes:

String query = "from user u where u.name like '%:name%'"

getHibernateTemplate().findByNamedParam(query, "name", str);

Didn’t work either, an org.hibernate.QueryParameterException: could not locate named parameter.

What actually worked was putting the “%” signs in the parameter:

String query = "from user u where u.name like :name"

getHibernateTemplate().findByNamedParam(query, "name", '%' + str + '%');