-
Installing Tomcat 6 on Debian Squeeze
This post describes how to setup Tomcat 6 on Debian Squeeze. The configured Tomcat serves requests on port 80 without the need of an additional web server. This is especially good for virtual servers (VPS) providing limit memory. It also has multiple virtual hosts configured, each with it’s own webapp with context root / and optional support for PHP via the Quercus PHP implementation.
Installing Sun Java 6
Ensure the non-free section is enabled for the APT repository configuration in /etc/apt/sources.list, e.g. “deb http://ftp.de.debian.org/debian testing main contrib non-free”
apt-get update apt-get install sun-java6-jdk echo 'JAVA_HOME="/usr/lib/jvm/java-6-sun"' >> /etc/environment echo 'JRE_HOME="/usr/lib/jvm/java-6-sun/jre"' >> /etc/environment
Installing Tomcat 6
apt-get install tomcat6 tomcat6-admin /etc/init.d/tomcat6 stop
Creating standard Tomcat directory layout
mkdir /opt/tomcat cd /opt/tomcat ln -s /etc/tomcat6/ conf ln -s /usr/share/tomcat6/bin/ bin ln -s /usr/share/tomcat6/lib/ lib ln -s /var/lib/tomcat6/webapps webapps ln -s /var/log/tomcat6/ logs
Creating a Tomcat admin user
In /opt/tomcat/conf/tomcat-users.xml add an entry like:
<user name="ADMIN_USERNAME" password="ADMIN_PASSWORD" roles="admin,manager" />
Setting up virtual hosts
For each virtual host execute the following command. Replace “mydomain.com” with the desired virtual host name, but omit the “www.” part.
mkdir -p /opt/tomcat/webapps.mydomain.com/ROOT
In the <Engine> tag of “/opt/tomcat/conf/server.xml” add one host entry for each virtual host.
<Host name="mydomain.com" appBase="/opt/tomcat/webapps.mydomain.com"> <Alias>www.mydomain.com>/Alias> <Valve className="org.apache.catalina.valves.AccessLogValve" prefix="mydomain_access_log." suffix=".txt" pattern="common"/> </Host>The <Alias> tag tells Tomcat to redirect from www.mydomain.com to mydomain.com.
The <Valve> tag enables access logging in the standard logging format.Using xinetd to configure port 80 for Tomcat
Binding a service on port 80 requires root permissions. Thus we use port forwarding to “bind” Tomcat to port 80. My VPS does not support the use of “iptables -j REDIRECT” therefore I am using xinetd as a web proxy.
Ensure that no other service is listening on port 80/443:netstat -pan | grep ":80\|:443"
Register the required xinetd services:
echo echo " service www { socket_type = stream protocol = tcp user = root wait = no bind = 88.80.198.181 port = 80 redirect = localhost 8080 disable = no flags = REUSE log_type = FILE /var/log/wwwaccess.log log_on_success -= PID HOST DURATION EXIT per_source = UNLIMITED instances = UNLIMITED } service https { socket_type = stream protocol = tcp user = root wait = no bind = 88.80.198.181 port = 443 redirect = localhost 8443 disable = no flags = REUSE log_type = FILE /var/log/httpsaccess.log log_on_success -= PID HOST DURATION EXIT per_source = UNLIMITED instances = UNLIMITED } " > /etc/init.d/tomcat /etc/init.d/xinetd restartIf you want to use a different service name, e.g. “tomcat” instead of “www” you must add this service to /var/services, e.g. “tomcat 80/tcp”
In /opt/tomcat/conf/server.xml modify the <Connector> as follows:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" proxyPort="80" address="127.0.0.1" />This binds Tomcat to localhost. It also tells Tomcat that port 80 is the proxy port which is necessary for correct URL generation.
From now on the Tomcat admin applications are only accessible via localhost. You can use SSH port forwarding to still access the applications from your workstation’s web browser. E.g. if you are using PuTTY you can use this command line option “-L 8080:localhost:8080″ to forward the server’s local 8080 port to your workstation’s local 8080 port. On your workstation’s browser you then simply enter http://localhost:8080/manager/html and are connected to the server’s Tomcat admin application.Enabling PHP support (optional)
Download Quercus.
mkdir -p /opt/downloads wget -o /opt/downloads/quercus-4.0.3.war http://caucho.com/download/quercus-4.0.3.war
Install Quercus as a shared library.
unzip -j /opt/downloads/quercus-4.0.3.war \*.jar -d /opt/tomcat/lib
Enable PHP support for the virtual hosts by installing the quercus web.xml. For each virtual host execute:
unzip /opt/downloads/quercus-4.0.3.war *web.xml -d /opt/tomcat/webapps.mydomain.com/ROOT
Starting Tomcat
/etc/init.d/tomcat start
References
-
Leveraging PyDev’s auto completion for indirectly created objects
This is just a quick tip how to enable auto completion in PyDev for indirectly created objects.
By default, PyDev has no problems in presenting you the possible object attributes and methods on a variable if that variable gets a new object instance assigned directly in the code.
For example, when you first type …
mybook = Book()
… and in the next line you enter …
mybook.
… PyDev will dutifully present you the statically declared features for the Book class in a popup.
If you however get that Book instance as the result of another method, e.g. …
mybook = bookstore.findBook("foobar")… PyDev currently seems to be helpless.
Because of Python’s dynamic nature it is of course a bit harder for an IDE to figure out what kind of objects may a method. But PyDev could for example honor the @return / @rtype PyDoc annotations (which you can add to the findBook’s method declaration) but currently it just does not.
To still have autocompletion you have two options:
- Temporarily instantiate a Book object in the code.
mybook = Book() mybook = bookstore.findBook("foobar") mybook. #--> now you have auto completionThis has the drawback, that if you forget to remove the first line before you finish coding an unneccessary Book instance will be created on every execution during runtime.
- Use an assertion to ensure that the mybook variable contains an object of type Book
mybook = bookstore.findBook("foobar") assert isinstance(mybook, Book) mybook. #--> now you have auto completion
- Temporarily instantiate a Book object in the code.
-
OVal 1.40 released
I am happy to announce the immediate availability of Version 1.40 OVal the Object Validation Framework for Java. This release fixes some minor issues and provides the following two new features:
1. Enabling/disabling constraints based on the object state:
Using the newly introduced when attribute for constraints it is possible to specify under which circumstances the constraint will be considered during object validation. The when attribute holds a formula in one of the supported scripting languages. If the formula returns true, the constraint will be activated for the current validation cycle otherwise it is ignored. In the following example the alias attribute must have a value only when the name attribute is not set.public class User { private String name; @NotNull(when = "groovy:_this.name == null") private String alias; // . . . }2. Fine grain control over how constraints are applied on arrays, maps, collections and their elements
The newly introduced attribute appliesTo allows you to specify if and how a constraint declared for a map, a collection or an array is applied to their elements as well or exclusively. See the following example how this works:public class BusinessObject { // the ids field may be null, but if it is not null // none of it's items must be null @NotNull(appliesTo = { ConstraintTarget.VALUES }) private String[] ids; // only the field itself must not be null, // the list can contain null values @NotNull(appliesTo = { ConstraintTarget.CONTAINER }) private List items; // the field must not be null as well as all keys // and values of the map @NotNull(appliesTo = { ConstraintTarget.CONTAINER, ConstraintTarget.KEYS, ConstraintTarget.VALUES }) private Map itemsByGroup; // . . . }Download
You can get the lates binaries and source files of OVal from here: http://sourceforge.net/projects/oval/files/ -
Comparing version numbers in Jython / Python
Here comes a function to compare version numbers of e.g. Maven artifacts in Jython / Python.
import re def cmpver(vA, vB): """ Compares two version number strings @param vA: first version string to compare @param vB: second version string to compare @author Sebastian Thomschke @return negative if vA < vB, zero if vA == vB, positive if vA > vB. Examples: >>> cmpver("0", "1") -1 >>> cmpver("1", "0") 1 >>> cmpver("1", "1") 0 >>> cmpver("1.0", "1.0") 0 >>> cmpver("1.0", "1") 0 >>> cmpver("1", "1.0") 0 >>> cmpver("1.1.0", "1.0.1") 1 >>> cmpver("1.0.1", "1.1.1") -1 >>> cmpver("0.3-SNAPSHOT", "0.3") -1 >>> cmpver("0.3", "0.3-SNAPSHOT") 1 >>> cmpver("1.3b", "1.3c") -1 >>> cmpver("1.14b", "1.3c") 1 """ if vA == vB: return 0 def num(s): if s.isdigit(): return int(s) return s seqA = map(num, re.findall('\d+|\w+', vA.replace('-SNAPSHOT', ''))) seqB = map(num, re.findall('\d+|\w+', vB.replace('-SNAPSHOT', ''))) # this is to ensure that 1.0 == 1.0.0 in cmp(..) lenA, lenB = len(seqA), len(seqB) for i in range(lenA, lenB): seqA += (0,) for i in range(lenB, lenA): seqB += (0,) rc = cmp(seqA, seqB) if rc == 0: if vA.endswith('-SNAPSHOT'): return -1 if vB.endswith('-SNAPSHOT'): return 1 return rcTheoretically lines 43 – 49 could be written in a more compact way but using the short circuit evaluations (as below) lead to wrong results – at least in Jython 2.1:
seqa = map(lambda s: s.isdigit() and int(s) or s, re.findall('\d+|\w+', vA.replace('-SNAPSHOT', ''))) seqb = map(lambda s: s.isdigit() and int(s) or s, re.findall('\d+|\w+', vB.replace('-SNAPSHOT', ''))) -
Running TomCat 6 in Debug Mode under Windows
While tracing some problems in one of my grails applications I had the need to do step debugging on a remote Tomcat server. Eventually I came up with the following lines to launch TomCat in debug mode:
@echo off set JPDA_TRANSPORT="dt_socket" set JPDA_ADDRESS="8000" set JPDA_SUSPEND="y" catalina.bat jpda start
Simply create a debug.bat file in TomCat’s bin directory and add these lines.
-
Lotus Notes’ [Send only] and [Send and File] buttons for Outlook 2003
You can say what you want about Lotus Notes, if you have used it for a while and switched e.g. to Outlook, you’ll find yourself missing one or the other nifty Notes function.
Already two of my customers “forced” me to use MS Outlook 2003 and since this isn’t likely to change in the near future, I implemented two of these handy Notes functions for Outlook 2003:
- The button [Send only] sends e-mails without storing a copy of it in the local mailbox.
- The button [Send and File...] prompts you for the folder where to store the e-mail being send.
Installation:
- Download the Visual Basic module in the favored language.
Send Mail Macros for MS Outlook 2003 (EN) (4.9 KiB, 675 hits)
Send Mail Macros for MS Outlook 2003 (DE) (5.1 KiB, 381 hits)
- In Outlook open the Visual Basic editor.

- Import the Visual Basic module.
- Save the project.
- Install the buttons in the toolbar.
- When composing a new e-mail the additional buttons should appear in the toolbar.
- When clicking “Send and File…” the folder dialog is displayed before the e-mail is send.



Looking for a high performer for your next IT project?


English
Deutsch
Recent Comments