Installation Steps
- Download and install Tomcat. It's usually as simple as unzipping it in a directory. Let's call this directory TOMCAT_HOME.
- Extract the XWiki WAR into a directory named xwiki in TOMCAT_HOME/webapps/. The reason you're expanding the WAR is because you'll need to modify one configuration file from inside the WAR later on when you configure the database access.
- Edit your conf/server.xml to set UTF-8 encoding: <Connector port="8080" ... URIEncoding="UTF-8"/>
- Make sure you give enough memory to Java since by default Tomcat is configured with not enough memory for XWiki.
Activate headless mode
If you're operating XWiki on a Linux server with no X11 libraries installed you have to enable headless mode for your Tomcat installation. Sometimes this is also needed on Windows platforms. Typical exceptions are:
- Exception: Could not initialize class sun.awt.X11.XToolkit
- java.lang.InternalError: Can't connect to X11 window server using 'localhost:10.0' as the value of the DISPLAY variable
- On Linux create a file /TOMCAT_HOME/bin/setenv.sh and insert the following code:#!/bin/sh
export JAVA_OPTS="${JAVA_OPTS} -Djava.awt.headless=true" - On Windows create a file /TOMCAT_HOME/bin/setenv.bat and insert the following code:set JAVA_OPTS=%JAVA_OPTS% -Djava.awt.headless=true
- When running as a Windows service the setenv.bat is not working. See registry HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Procrun 2.0\FOOBAR\Parameters\Java for similar settings.
Optional configuration
- Edit your conf/server.xml to enable gzip compression: <Connector port="8080" ... compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/css,text/javascript,application/x-javascript"/>
- If you want to modify the port on which Tomcat will run, edit TOMCAT_HOME/conf/server.xml/. Search for 8080 (sometimes 8180 if you are under Linux) and replace with the port value you wish to use.
- It is possible to setup a Tomcat Java Server as a UNIX Daemon - JSVC. Just follow these instructions. The only reason to make Tomcat a daemon is to make it runnable on the 80th port, which can be replaced by using NginX as a proxy on the 80th port and then forwarding to Tomcat to the 8080th port.
Policy configuration
For those who activate the security manager for Tomcat, add this portion of code to the end of your conf/catalina.policy file from your Tomcat installation. You can adapt the code for the available installations of OpenOffice/LibreOffice on your server and for different databases :
// for mySQL connection
permission java.net.SocketPermission "127.0.0.1:3306", "connect,resolve";
// XWiki must have access to all properties in read/write
permission java.util.PropertyPermission "*", "read, write";
// Generic detected permissions
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
permission java.lang.RuntimePermission "createClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.loader";
permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.RuntimePermission "getenv.ProgramFiles";
permission java.lang.RuntimePermission "getenv.APPDATA";
permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.connector";
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.util.threads";
permission java.lang.RuntimePermission "reflectionFactoryAccess";
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.jmx.interceptor";
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.jmx.mbeanserver";
permission java.lang.RuntimePermission "modifyThread";
permission java.lang.RuntimePermission "getProtectionDomain";
// JAXB permissions
permission javax.xml.bind.JAXBPermission "setDatatypeConverter";
// Serialization related permissions
permission java.io.SerializablePermission "allowSerializationReflection";
permission java.io.SerializablePermission "creator";
permission java.io.SerializablePermission "enableSubclassImplementation";
// Internal resources access permissions
permission java.io.FilePermission "synonyms.txt", "read";
permission java.io.FilePermission "lang/synonyms_en.txt", "read";
permission java.io.FilePermission "quartz.properties", "read";
permission java.io.FilePermission "/templates/-", "read";
permission java.io.FilePermission "/skins/-", "read";
permission java.io.FilePermission "/resources/-", "read";
// MBean related permissions
permission javax.management.MBeanServerPermission "createMBeanServer";
permission javax.management.MBeanPermission "*", "registerMBean";
permission javax.management.MBeanPermission "*", "unregisterMBean";
permission javax.management.MBeanTrustPermission "register";
permission javax.management.MBeanPermission "-#-[-]", "queryNames";
permission javax.management.MBeanServerPermission "findMBeanServer";
// LibreOffice/OpenOffice related permissions
permission java.io.FilePermission "/opt/openoffice.org3/program/soffice.bin", "read";
permission java.io.FilePermission "/opt/libreoffice/program/soffice.bin", "read";
permission java.io.FilePermission "/usr/lib/openoffice/program/soffice.bin", "read";
permission java.io.FilePermission "/usr/lib/libreoffice/program/soffice.bin", "read";
// Allow file storage directory reading - for directory and everything underneath
// This is dependent on the setting of environment.permanentDirectory in xwiki.properties
permission java.io.FilePermission "${catalina.base}${file.separator}xwikidata${file.separator}", "read,write,delete";
permission java.io.FilePermission "${catalina.base}${file.separator}xwikidata${file.separator}-", "read,write,delete";
// Allow file storage directory reading - temporary directory and everything underneath
// This is dependent on the setting of environment.temporaryDirectory in xwiki.properties.
permission java.io.FilePermission "${catalina.base}${file.separator}temp${file.separator}", "read,write,delete";
permission java.io.FilePermission "${catalina.base}${file.separator}temp${file.separator}-", "read,write,delete";
};
Please note that this policy configuration file have been tested on CentOS 5.9 with Sun JDK 1.7.0u21 on Tomcat 7.0.40 with XWiki 5.0.1 installed.
Nginx proxying for Tomcat applications
As Tomcat is not a true web server, it's worth to use it as backend. Nginx is one of the best solutions for the frontend web server.
So, after a typical XWiki installation we have XWiki running on http://localhost:8080/xwiki. Most probably, we want to access XWiki via http://mydomain.com on standard 80 port. Tuning Nginx will give us the desired result:
- create this file /etc/nginx/conf.d/tomcat.conf
- put the following code inside:server {
listen 80;
server_name mydomain.com;
# Root to the XWiki application
root /opt/tomcat/webapps/xwiki;
location / {
#All "root" requests will have /xwiki appended AND redirected to mydomain.com again
rewrite ^ $scheme://$server_name/xwiki$request_uri? permanent;
}
location ^~ /xwiki {
# If path starts with /xwiki - then redirect to backend: XWiki application in Tomcat
# Read more about proxy_pass: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
}
} - restart nginx
Now all http://mydomain.com/* requests will lead to the XWiki application. Please note that these settings are basic. For more flexible solutions please refer to the Nginx documentation.
HTTPS setting
- If using HTTPS for accessing XWiki, several modifications have to be made to ensure flawless functionality. Since urls are generated from relative path (/xwiki/bin/show/Space/Page), Tomcat has to know which protocol to use, otherwise JSON requests with redirect fails (attachment uploads, extension updating, etc.)
- Modify connector (in server.xml) to <Connector port="8080" ... secure="true" scheme="https" />
- Modify host (in server.xml) and add Remote Ip Valve <Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="x-forwarded-for" protocolHeader="x-forwarded-proto" /> (only needed if using another server for HTTPS)
Troubleshooting
Out Of Memory Error
When you run XWiki in Tomcat with the default settings, you'll probably get an Out Of Memory error (java.lang.OutOfMemoryError: Java heap space or java.lang.OutOfMemoryError: PermGen space) since the default Tomcat memory settings are not enough for XWiki Memory Requirements. You'll need to allocate more memory to the JVM.
One easy solution to configure Tomcat's memory is to create a setenv.sh file (or setenv.bat on Windows) in [TOMCAT_HOME]/bin/ (where [TOMCAT_HOME] is where you've installed Tomcat) and inside this file add the following (adjust the memory values according to the XWiki Memory Requirements). For example:
On most Linux distributions, this can also be achieved in /etc/tomcatX/tomcatX.conf or /etc/conf.d/tomcatX.conf (where X is the version of Tomcat installed).
On Windows, if you are running Tomcat as a service then defining CATALINA_OPTS will not help. There is an utility provided in the bin folder of your Tomcat installation (for example for Tomcat 5.x on Windows it's called tomcat5w.exe). It's a GUI tool which can be used to set various options including the heap size.
Java Security Manager
By default Tomcat is configured to have the Java Security Manager turned on. See the sample policy file for more details.
If you want to turn off the Java Security Manager for Tomcat, edit the Tomcat startup script. You might also want to check your /etc/init.d/tomcat file or /etc/default/tomcat5.5. You should see the following code:
TOMCAT5_SECURITY=
Set it to no to turn off the Security Manager.
Allowing "/" in page names
Tomcat completely freaks out when there's a %2F in URLs and it's not something that can be changed in XWiki. See this note for more information.
You can configure Tomcat to allow this, by enabling :
Note that if you're using Apache you also need to configure Apache to allow encoded / and \.
NotSerializableException
If you get the following:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.xwiki.model.internal.reference.LocalStringEntityReferenceSerializer
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
This means that on startup Tomcat tries to load saved Sessions and fails to do so. In this case it fails because some non-serializable object was put in the Servlet Session. To work around the issue you can tell Tomcat to not save sessions.
SEVERE: Error listenerStart
If you get this error in your Tomcat logs then you'll need to enable finer-grained logging configuration to see what's the problem. For Tomcat 6.x/7.x this involves copying the following content in a WEB-INF/classes/logging.properties file:
org.apache.catalina.core.ContainerBase.[Catalina].handlers = java.util.logging.ConsoleHandler