Installation and Upgrade > Installing ThingWorx > Manual Installation > Ubuntu Installation > Install Java, Apache Tomcat, and ThingWorx
Install Java, Apache Tomcat, and ThingWorx
In the steps below, replace xx or xxx with the build number you are using.
Copying and pasting the commands in these procedures can cause formatting issues. If necessary, copy and paste into a text editor to minimize formatting issues.
Install Java and Apache Tomcat
1. Update Ubuntu packages:
$ sudo apt-get update
2. Install and Configure Network Time Protocol (NTP) settings for time synchronization. The default configuration for NTP is sufficient. For additional configuration information about NTP (beyond the scope of this documentation), refer to the following resources:
$ sudo apt-get install ntp
3. Edit AUTHBIND properties to allow Tomcat to bind to ports below 1024:
$ sudo apt-get install authbind
4. Refer to the ThingWorx System Requirements for version requirements.
5. Download and install the required version of Java.
9.0: Java
9.1 and later: OpenJDK or Java 11.
You can install OpenJDK as shown in steps 6–12 below or use sudo apt install openjdk-11-jdk to install the latest using the package manager.
6. Extract the tar file:
The examples below use jdk-11.x.x, but replace with the version you are using if necessary.
tar -xf jdk-11.x.x_linux-x64_bin.tar.gz
7. Create the directory by moving the JDK to /usr/lib/jvm. If the directory is not empty, a warning message will display.
$ sudo mkdir -p /usr/lib/jvm
$ sudo mv jdk-11.x.x/ /usr/lib/jvm/
8. Add alternatives to the system:
$ sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk-11.x.x/bin/java" 1
$ sudo update-alternatives --install "/usr/bin/keytool" "keytool" "/usr/lib/jvm/jdk-11.x.x/bin/keytool" 1
9. Change access permissions:
$ sudo chmod a+x /usr/bin/java
$ sudo chmod a+x /usr/bin/keytool
10. Change owner:
$ sudo chown -R root:root /usr/lib/jvm/jdk-11.x.x/
11. Configure master links:
$ sudo update-alternatives --config java
$ sudo update-alternatives --config keytool
Nothing to configure is a normal response to this command and is not an error. Additional executables in /usr/lib/jvm/jdk-11.x.x/bin/ can be installed using the previous set of steps.
12. Verify Java version:
$ java -version
This should return something similar to the following (build specifics may be different):
java version "11.0.9" 2020-10-20 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.9+7-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.9+7-LTS, mixed mode)
13. Download Apache Tomcat. The steps in this process use Tomcat 9.0.xx, where xx is replaced with the version you are using.
$ wget
Best practice includes verifying the integrity of the Tomcat file by using the signatures or checksums for each release. Refer to Apache’s documentation for more information.
14. Extract the TAR file:
$ tar -xf apache-tomcat-9.0.xx.tar.gz
15. Create and change the owner for /usr/share/tomcat9.0 and move Tomcat to the following location. Add user and group to the system:
$ sudo mkdir -p /usr/share/tomcat9.0
$ sudo mv apache-tomcat-9.0.xx /usr/share/tomcat9.0/9.0.xx
$ sudo addgroup --system tomcat9.0 --quiet -force-badname
$ sudo adduser --system --home /usr/share/tomcat9.0/ --no-create-home --ingroup tomcat9.0 --disabled-password --force-badname --shell /bin/false tomcat9.0
$ sudo chown -R tomcat9.0:tomcat9.0 /usr/share/tomcat9.0
16. Create and change access permissions for usr/share/tomcat9.0/ignite:
Perform this step if you are deploying the ThingWorx HA server.
cd /usr/share/tomcat9.0
mkdir ignite
chown -Rh tomcat9.0:tomcat9.0 ignite
17. Define environment variables in /etc/environment (as root):
export JAVA_HOME=/usr/lib/jvm/jdk-11.x.x_xxx
export CATALINA_HOME=/usr/share/tomcat9.0/9.0.xx
18. Reflect environment variables:
source /etc/environment
19. Change directory to $CATALINA_HOME:
20. Change owner and access permissions of bin/, lib/, and webapps/:
$ sudo chown -Rh tomcat9.0:tomcat9.0 bin/ lib/ webapps/
$ sudo chmod 770 bin/ lib/ webapps/
21. Change owner and access permissions of usr/share/tomcat9.0/9.0.xx:
$ sudo chown -R tomcat9.0:tomcat9.0 /usr/share/tomcat9.0/9.0.xx
$ sudo chmod -R 770 /usr/share/tomcat9.0/9.0.xx
22. Change owner and access permissions of conf/:
$ sudo chown -Rh root:tomcat9.0 conf/
$ sudo chmod -R 650 conf/
23. Change access permissions of logs/, temp/, and work/:
$ sudo chown -R tomcat9.0:tomcat9.0 logs/ temp/ work/
$ sudo chmod 760 logs/ temp/ work/
24. Create a self-signed certificate:
$ sudo $JAVA_HOME/bin/keytool -genkey -alias tomcat9.0 -keyalg RSA -keystore $CATALINA_HOME/conf/.keystore
25. Follow the instructions to complete the certificate creation process.
Set the KeyStore password.
Follow the prompts to set up your security certificate.
Set the tomcat9.0 user password to the same as the keystore password:
$ sudo chown root:tomcat9.0 $CATALINA_HOME/conf/.keystore
$ sudo chmod 640 $CATALINA_HOME/conf/.keystore
26. Uncomment the Manager element in $CATALINA_HOME/conf/context.xml to prevent sessions from persisting across restarts:
<Manager pathname="" />
For security reasons, it is critical that you disable the AJP connector, if it not disabled by default, by performing the following step.
27. In the location of the Tomcat installation, open $CATALINA_HOME/conf/server.xml and search for the following line. If found, comment it out and save the file:

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
In Apache Tomcat 9.0 and later, the rejectIllegalHeader attribute defaults to true. Manually modifying the conf/web.xml file to set this attribute to false is not recommended or supported by PTC.
If youreceive an error that the directory does not exist, use the following commands to ensure port 443 works:
$ sudo touch /etc/authbind/byport/443
$ sudo chmod 700 /etc/authbind/byport/443
$ sudo chown tomcat9.0:tomcat9.0 /etc/authbind/byport/443
28. Define a user in $CATALINA_HOME/conf/tomcat-users.xml:
$ sudo vi $CATALINA_HOME/conf/tomcat-users.xml
<user username="<Tomcat user name> " password="<Tomcat password> " roles="manager"/>
29. Determine the uid of tomcat9.0 user:
$ id -u tomcat9.0
30. Using this number, create an ID file in /etc/authbind/byuid/. Change the <uid> to the number that was returned in the previous step:
$ sudo touch /etc/authbind/byuid/<uid>
$ sudo vi /etc/authbind/byuid/<uid>
31. Edit the file from the previous step and paste in the following:,1023
32. Change owner and access permissions of/etc/authbind/byuid/<uid>:
$ sudo chown tomcat9.0:tomcat9.0 /etc/authbind/byuid/<uid>
$ sudo chmod 700 /etc/authbind/byuid/<uid>
33. Modify $CATALINA_HOME/bin/ to always use authbind:
sudo vi $CATALINA_HOME/bin/
Comment the following in the file:
#exec "$PRGDIR"/"$EXECUTABLE" start "$@"
34. Add the following to the end of the file:
exec authbind --deep "$PRGDIR"/"$EXECUTABLE" start "$@"
35. In /etc/init.d, create tomcat9.0 file:
$ sudo touch /etc/init.d/tomcat9.0
36. Edit the file and enter the following contents:
$ sudo vi /etc/init.d/tomcat9.0


case $1 in
/bin/su -p -s /bin/sh tomcat9.0 $CATALINA_HOME/bin/

/bin/su -p -s /bin/sh tomcat9.0 $CATALINA_HOME/bin/

/bin/su -p -s /bin/sh tomcat9.0 $CATALINA_HOME/bin/
/bin/su -p -s /bin/sh tomcat9.0 $CATALINA_HOME/bin/

exit 0
37. Change access permissions of etc/init.d/tomcat9.0 and create symbolic links:
$ sudo chmod 755 /etc/init.d/tomcat9.0
$ sudo ln -s /etc/init.d/tomcat9.0 /etc/rc1.d/K99tomcat
$ sudo ln -s /etc/init.d/tomcat9.0 /etc/rc2.d/S99tomcat
38. Set up Tomcat as a service to start on boot. First, build JSVC. If JSVC is already installed on your system go to the next step.
$ sudo apt-get install gcc
39. Set up the Tomcat service on boot:
$ cd /usr/share/tomcat9.0/9.0.xx/bin/
$ sudo tar xvfz commons-daemon-native.tar.gz
$ cd commons-daemon-*-native-src/unix
$ sudo ./configure --with-java=$JAVA_HOME
$ sudo apt-get install make
$ sudo make
$ sudo cp jsvc ../..
40. Create the Tomcat service file:
$ sudo touch /etc/systemd/system/tomcat9.0.service
41. Open /etc/systemd/system/tomcat9.0.service in a text editor (as root):
$ sudo vi /etc/systemd/system/tomcat9.0.service
a. Paste the following in the Tomcat service file:
In the example below, set values for -Xms and -Xmx to 75% of the available OS memory (for example, 12GB for a 16GB RAM system). Refer to JVM Tuning for additional information.
Description=Apache Tomcat Web Application Container

Environment="JAVA_OPTS=-Djava.awt.headless=true -Dserver -Dd64 -XX:+UseNUMA -Dlog4j2.formatMsgNoLookups=true -XX:+UseG1GC -Dfile.encoding=UTF-8 -Xms256M -Xmx512M -Djava.library.path=${CATALINA_BASE}/webapps/Thingworx/WEB-INF/extensions -DIGNITE_HOME=/usr/share/tomcat/9.0.79/ignite"

ExecStart=/usr/share/tomcat9.0/9.0.xx/bin/jsvc \
-DIGNITE_HOME=/usr/share/tomcat9.0/ignite \”
-Dcatalina.home=${CATALINA_HOME} \
-Dcatalina.base=${CATALINA_BASE} \
-Djava.awt.headless=true -Dserver -Dd64 -XX:+UseNUMA -Dlog4j2.formatMsgNoLookups=true \
-XX:+UseG1GC -Dfile.encoding=UTF-8 \
-Xms=<75% of available OS memory> \
-Xmx=<75% of available OS memory> \
-Djava.library.path=${CATALINA_BASE}/webapps/Thingworx/WEB-INF/extensions \
-cp ${CATALINA_HOME}/bin/commons-daemon.jar:${CATALINA_HOME}/bin/bootstrap.jar:${CATALINA_HOME}/bin/tomcat-juli.jar \
-user tomcat9.0 \
-java-home ${JAVA_HOME} \
-pidfile /var/run/ \
-errfile ${CATALINA_HOME}/logs/catalina.out \
-outfile ${CATALINA_HOME}/logs/catalina.out \

b. Set Tomcat to run on system start up:
$ sudo systemctl daemon-reload
$ sudo systemctl enable tomcat9.0.service
c. If the Tomcat service doesn't automatically start after reboot and you receive the following error on executing sudo systemctl enable tomcat9.0.service:
update-rc.d: error: tomcatx.x Default-Start contains no runlevels, aborting.
then the following step is required:
Remove the tomcat9.0.service file located at /etc/init.d and rerun the following command:
$ sudo systemctl daemon-reload
$ sudo systemctl enable tomcat9.0.service
d. If you receive the following error:
insserv: warning: script 'tomcat9.0' missing LSB tags and override
add the following to /etc/systemd/system/tomcat9.0.service:

# Provides: tomcat8.5
# Required-Start: $local_fs $network
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: tomcat8.5
# Description: tomcat8 service
sudo service tomcat9.0 start
42. If you are installing the ThingWorx Platform for the first time, the Java option -Duser.timezone=UTC should be added to the ExecStart block above, immediately following the line that begins with -Djava.library.path. The UTC timezone does not recognize daylight savings time. Setting this option prevents overwriting data when daylight savings time changes occur.
43. If installing on Apache Ignite 2.14.0 or newer and on Ubuntu 22.04, set var in
44. Create a new file in the tomcat /bin directory named
$ sudo touch
$ sudo vi
CATALINA_OPTS="$CATALINA_OPTS -Djava.library.path=/usr/share/tomcat9.0/9.0.xx/webapps/Thingworx/WEB-INF/extensions"
45. In the location of the Tomcat installation, open $CATALINA_HOME/conf/web.xml. Replace the default error page (default is stacktrace) by adding the following into the web.xml file. Place the following within the web-app tag (after the welcome-file-list tag ). A well-configured web application will override this default in $CATALINA_HOME/webapps/APP_NAME/WEB-INF/web.xml so it won't cause problems.
46. In the location of the Tomcat installation, open $CATALINA_HOME/conf/server.xml. Add the following inside the <Host> </Host> tags:
<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" />
47. Remove all Tomcat example webapps (docs, examples, host-manager, manager, ROOT) located in /<path_to_tomcat>/webapps/. Removing these apps prevents unnecessary access to Tomcat, specifically in the context that allows users to view other users' cookies.
48. PTC strongly recommends the use of TLS when running ThingWorx. For detailed instructions on setting up TLS, refer to this technical support article.
49. If your application requires a specific cipher suite, refer to the following documentation for configuration information:
50. (OPTIONAL STEP) To increase the default cache settings that affect static file caching, add the following line within the <Context></Context> tags in the $CATALINA_HOME/conf/context.xml file:
<Resources cacheMaxSize="501200" cacheObjectMaxSize="2048" cacheTtl="60000"/>
Increasing this setting improves performance and avoids the following message in Tomcat:
WARNING: Unable to add the resource at [/Common/jquery/jquery-ui.js] to the cache because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache
Install ThingWorx
1. Create /ThingworxStorage and /ThingworxBackupStorage directories. If you haven’t already done so, create the /ThingworxPlatform directory as well:
$ sudo mkdir /ThingworxStorage /ThingworxBackupStorage /ThingworxPlatform
2. Change owner and access permissions of /ThingworxPlatform, /ThingworxStorage and /ThingworxBackupStorage. Without these permissions, the server will fail to start.
These folders must have appropriate ownership and access rights. They should be owned by the same user who runs the Tomcat service, and should have full control assigned to that user. This user is generally NETWORK_SERVICE, but may differ in your environment. Without these permissions, the server will fail to start.
$ sudo chown tomcat9.0:tomcat9.0 /ThingworxStorage /ThingworxBackupStorage /ThingworxPlatform
$ sudo chmod 775 /ThingworxStorage /ThingworxBackupStorage /ThingworxPlatform
3. Obtain the appropriate Thingworx.war file for the database you are using. The latest ThingWorx downloads are posted at under Download Software > Order or Download Software Updates > ThingWorx Foundation > Release X.X > ThingWorx PostgreSQL, ThingWorx Mssql, ThingWorx H2, or ThingWorx AzureSql > Most Recent Version > ThingWorx-Platform-<database type>-<version>.
4. Move the Thingworx.war to $CATALINA_HOME/webapps.
$ sudo mv Thingworx.war $CATALINA_HOME/webapps
$ sudo chown tomcat9.0:tomcat9.0 $CATALINA_HOME/webapps/Thingworx.war
$ sudo chmod 775 $CATALINA_HOME/webapps/Thingworx.war
5. Place the platform-settings.json in the ThingworxPlatform folder.
If you are using H2, you must create the platform-settings.json file, as it is not included in the download.

$ sudo cp platform-settings.json /ThingworxPlatform/
6. Perform this step if you are using H2 as a database. If you are not using H2 as a database, go to the next step. Add a username and password for H2 in the platform-settings.json file. See platform-settings.json Configuration Details for more information.
ThingWorx connections to the H2 database require a username and password defined by the user, or the server will not start. This design fully mitigates any potential vulnerability represented by CVE-2018-10054.
"password": "<addsecurepassword>",
"username": "twadmin"
7. Skip this step if you are not using Azure SQL or Azure PostgreSQL Flexible Server as a database. If you are using Azure SQL, open the platform-settings.json file and add the following Azure SQL persistence provider parameters:
"PersistenceProviderPackageConfigs": {
"AzuresqlPersistenceProviderPackage": {
"ConnectionInformation": {
"driverClass": "",
"jdbcUrl": "jdbc:sqlserver://<server name>:<port>;databaseName=thingworx;applicationName=Thingworx;",
"password": "<database password>",
"username": "twadmin"
If you are using Azure PostgreSQL Flexible Server, open the platform-settings.json file and add the following Azure PostgreSQL Flexible Server persistence provider parameters:
"PostgresPersistenceProviderPackage": {
"ConnectionInformation": {
"jdbcUrl": "jdbc:postgresql://<server name>:<port>/<database name>",
"password": "<password>",
"username": "<username>",
"sslMode": "require",
"sslRootCert": "<certificate path>"
For more information about different SSL modes, see PostgreSQL Documentation.
sslRootCert is required for verify-ca and verify-full SSL modes. For more information about secure communication with Azure PostgreSQL Flex Server and to download the certificate, see Encrypted connectivity using TLS/SSL in Azure Database for PostgreSQL — Flexible Server.
8. Configure the Administrator password.
Add the following AdministratorUserSettings section (in PlatformSettingsConfig) to your platform-settings.json file along with a password that is at least 14 characters long. Refer to platform-settings.json Configuration Details for more information on placement. Refer to Passwords for additional information on setting passwords.
Do not copy and paste the sample below, as it may cause bad formatting in your platform-settings.json. Instead, click here and copy from the file.

"PlatformSettingsConfig": {
"AdministratorUserSettings": {
"InitialPassword": "changeme"
If Tomcat fails to start and reports the error message: Check the InitialPassword setting in the AdministratorUserPassword section in platform-settings.json, check the following:
The password setting exists in platform-settings.json
The password is valid (14 or more characters by default)
The platform-settings.json file is formatted correctly - bad formatting could lead to errors
9. If you are installing ThingWorx 5.0.1 and newer, configure Content Security Policy (CSP).
a. Add "EnableContentSecurityPolicyFilter": false, to platform-settings.json under BasicSettings as follows.
"PlatformSettingsConfig": {
"BasicSettings": {
"BackupStorage": "/ThingworxBackupStorage",
"DatabaseLogRetentionPolicy": 7,
"DatabaseWriteRetryAttempts": 10,
"EnableBackup": true,
"EnableClusteredMode": false,
"EnableContentSecurityPolicyFilter": false,
"EnableSystemLogging": false,
"EnableSSO": false,
"FileRepositoryRoot": "/ThingworxStorage",
"FileTransferLockType" : "LOCAL"
"HTTPRequestHeaderMaxLength": 2000,
"HTTPRequestParameterMaxLength": 2000,
"InternalAesCryptographicKeyLength": 128,
"MetricsLoggingFrequency": 30,
"MetricsLoggingLevel": "WARN",
"MetricsReportingEnabled": true,
"NonceKeyTimeout": 15,
"SessionUpdateDelay": 60,
"Storage": "/ThingworxStorage",
"ScriptTimeout": 30,
"MaxSearchItems": 100000
CSP will be disabled in the new installation if the above flag is not added or is specifically set to false. Setting the flag to true will enable CSP. For more information about CSP, see Content Security Policy.
10. Enable extension import. By default, extension import is disabled for all users.
Add the following to the platform-settings.json file under PlatformSettingsConfig. Update the following ExtensionPackageImportPolicy parameters to true to allow extensions to be imported. See Importing Extensions for best practices on configuration.
"ExtensionPackageImportPolicy": {
"importEnabled": <true or false>,
"allowJarResources": <true or false>,
"allowJavascriptResources": <true or false>,
"allowCSSResources": <true or false>,
"allowJSONResources": <true or false>,
"allowWebAppResources": <true or false>,
"allowEntities": <true or false>,
"allowExtensibleEntities": <true or false>
11. If you are not using H2 for your database, go to Database Installation and Configuration to set up your database. Return to the next step after your database is configured. If you are using H2, proceed to the next step.
12. Configure licensing:
Open the platform-settings.json file and add the following to the PlatformSettingsConfig section. Refer to platform-settings.json Configuration Details.
If you are performing a disconnected installation (no internet access), you do not need to add the licensing information to the platform-settings.json file. Refer to the Licensing for ThingWorx Platform for disconnected sites and skip this step.
"PersistenceProviderPackageConfigs": {
"PostgresPersistenceProviderPackage": {
"ConnectionInformation": {
"jdbcUrl": "jdbc:postgresql://localhost:5432/thingworx",
"password": "<password>",
"username": "<username>"
"PlatformSettingsConfig": {
"LicensingConnectionSettings": {
If the settings are filled out incorrectly or if the server cannot connect, a License Request text file (licenseRequestFile.txt) is created in the ThingworxPlatform folder. In this scenario, a license must be created manually. If the license is not created, ThingWorx will start in limited mode. Limited mode does not allow you to persist licensed entities to the database. Licensed entities are Things, mashups, masters, gadgets, users, and persistence providers)
For more information on obtaining a ThingWorx disconnected site license through our License Management site, refer to the Licensing for ThingWorx Platform for disconnected sites (no connection to PTC Support portal). In this situation, if the license file is manually generated, it must be renamed to license_capability_response.bin and placed in the ThingworxPlatform folder.
For licensing troubleshooting, refer to PTC Support Article - CS271439.
13. Encrypt the license server password by following the steps in Encrypting Passwords.
14. If you are using Azure SQL as your database, follow these steps to download the JDBC driver. Skip this step if you are not using Azure SQL.
a. Go to the Azure portal and navigate to your ThingWorx database.
b. Select Connection strings.
c. Select the JDBC tab.
d. Select Download Microsoft JDBC Driver for SQL Server.
e. Select Microsoft JDBC Driver 6.0 for SQL Server.
f. Extract and copy the downloaded binary in your ThingWorx VM to your Tomcat lib directory.
15. Start Tomcat.
sudo service tomcat9.0 start
Verify that a license file (successful_license_capability_response.bin) is created in the ThingworxPlatform folder.
16. To launch ThingWorx, go to http://<servername>:<port>/Thingworx in a Web browser.
17. Change the initial Administrator password:
a. In Composer, select Administrator > Change Password.
b. In the Change Password window, enter Current Password, New Password, and Confirm Password.
The password, which should not be easily guessed or a known, common password, is recommended to be at least 14 characters in length and should include a mix of uppercase and lowercase letters, numbers, and special characters.
c. Delete the initial password from the platform-settings.json file.
18. Select Done.
19. (OPTIONAL STEP) To determine the status of your license, open the Monitoring>Subsystem>Licensing Subsystem Settings in Composer to confirm the list of features (licensed entities) included with the license. If there are no licensed entities present, you are in limited mode.
Was this helpful?