Upgrading to WildFly

PerformanceBridge has changed J2EE containers from GlassFish to Wildfly to support JRuby 9 and Java 8. This guide outlines the changes needed for a Rails application to deploy to production in the new environment.

Updating to Java 8 on Ubuntu 14.04

Java 8 is not available through the Trusty repository of Ubuntu 14.04. While multiple workarounds exist, we recommend using apt and update-alternatives so you can switch between Java versions as needed. To install Java 8 on Ubuntu 14.04:

sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk
sudo update-alternatives --config java # select java version
sudo update-alternatives --config javac # select java compile version
java -version # Check java version # Optional step to confirm java version

Changing JRuby version

Once Java 8 is installed, install JRuby 9.1.5.0. Using rvm, run the following:

rvm install jruby-9.1.5.0
rvm use jruby-9.1.5.0
gem install bundler

Updating JRuby and Warbler

First, update the Gemfile to upgrade jruby-jars and warbler:

gem 'jruby-jars', '=9.1.5.0' # Lock down our jruby version
gem 'warbler','~> 2.0.4' # We need warbler to build our war file
#Also comment out any 'rubyzip' or 'jruby-openssl' line

Warning - There is a known issue with redeploying JRuby 9.1.7.0 in a J2EE container. The fix is slated for JRuby 9.1.8.0.

Next, clean up the target directory and update the Gemfile.lock:

#from your rails root
rm -Rf target/*
bundle install

Adding the jboss-deployment-structure.xml

Wildfly uses a different class loading scheme than GlassFish or Tomcat. It is module-based instead of a traditional, heirarchical class loader. This allows for better dependency management and avoids race conditions in class loading, but requires specifying the inclusion of the harbinger.sdk module through the jboss-deployment-structure.xml. Create this file in the root of your Rails application with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
  <deployment>
    <exclude-subsystems>
      <subsystem name="jpa" />
    </exclude-subsystems>
    <dependencies>
      <module name="harbinger.sdk" />
    </dependencies>
  </deployment>
</jboss-deployment-structure>

You need to specify where to include the file in the WAR by adding this line to config/warble.rb:

Warbler::Config.new do |config|
  #...
  config.webinf_files += FileList["jboss-deployment-structure.xml"] # This is the new line
end

Updating the database connection

The JNDI location of the production database has changed. Instead of the jndi/appName convention, use java:/jdbc/appName. An example config/database.yml:

production:
  adapter: postgresql
  jndi: java:/jdbc/railsdevelopertutorial

The create-glassfish-jdbc.sh script will need to be replaced with create-wildfly-jdbc.sh. The script should contain the following with the appropriate schemaName and login credentials:

$CLI -c "data-source add --jndi-name=java:/jdbc/schemaName --name=schemanamePool --connection-url=jdbc:postgresql://localhost:5432/harbinger --driver-name=postgres --user-name=somedatabaseusername --password=somepasswordyougive --max-pool-size=8 --min-pool-size=2 --idle-timeout-minutes=5 --flush-strategy=Gracefully"

Updating warblizer script

Finally, update the warblizer.sh to remove the PermGenSpace warnings (there is no longer a seperate heap for Java classes in Java 8). The updated warbilizer.sh:

#!/bin/bash

APPNAME=`cat config/application.name`

# Standard file changes
echo "Warblizer: Creating version page"
git describe --always > app/views/main/_version.html.erb

# Warbalizing with changed files

echo "Warblizer: Bundling"
RAILS_ENV=production jruby -S bundle install --path=target

echo "Warblizer: Pre Cleaning Assets"
ASSETS="clean" RAILS_ENV=production jruby -S bundle exec rake assets:clean

echo "Warblizer: Precompiling Assets (this takes a while)"
JRUBY_OPTS="-J-Xmx1024m" ASSETS="precompile" RAILS_RELATIVE_URL_ROOT="/$APPNAME" RAILS_ENV=production -S bundle exec rake assets:precompile

echo "Warblizer: Building War File"
WARRING="warbilizing" RAILS_ENV=production jruby -S bundle exec warble compiled war

echo "Warblizer: Post Cleaning Assets"
ASSETS="clean" RAILS_ENV=production jruby -S bundle exec rake assets:clean

echo "Warblizer: Changing permissions and war file name"
chmod +r "$APPNAME.war"
mv -v "$APPNAME.war" "$APPNAME.war.`git describe --always`"

# Resetting standard files
git checkout app/views/main/_version.html.erb

Updating development environments

In previous platform releases, you needed to have a GlassFish instance available to supply the required JNDI properties and database connection. This is no longer needed, you now use a special configuration file added to the classpath, either through an EXPORT call or at runtime in the launch scripts.

First, create the new configuration file in the root of the application and call it jndi-config.clj:

{:names {}
 :properties {"java:global/harbinger-config"
              {"cometd-amqp.url" "http://localhost/cometd-amqp/cometd"
               "apm-host" "localhost"
               "apm-port" "4000"
               "harbinger.amqp.host" "localhost"
               "harbinger.amqp.user" "guest"
               "harbinger.amqp.password" "guest"}
              "harbinger-jpa-config"
              {"hibernate.search.default.indexBase" "/path/to/lucene/indexes"}}

 :data-sources {"java:/jdbc/harbinger"
                {:database "harbinger" :server "localhost" :user "roharbinger" :password "harbinger-user-password"}}}

Also, create a jndi.properties configuration file in the root of the application:

java.naming.factory.initial=harbinger.jndi.InitialContextFactory

Without a J2EE server providing database configuration, you need to update the development database in the config/database.yml file to include credentials. An example:

development:
  adapter: postgresql
  host: localhost
  username: railsdevelopertutorial
  password: 2893ourj8923urjl
  database: harbinger

Updated launch scripts:

launch_dev_server

CLASSPATH="$CLASSPATH:./jndi-config.clj" DEV_MODE="on" JRUBY_OPTS="-J-Dharbinger.sso.url=http://ai-openam-server.com:8088/openam" rails server

launch_dev_console

CLASSPATH="$CLASSPATH:./jndi-config.clj" DEV_MODE="on" rails console