Pages

Saturday, January 6, 2018

Setting up JRebel for WebSphere AS in Docker environment

Getting any Java application server up and running in the development environment is usually a fairly simple task. You can just download the zip archive, and start the contain either from command line or via IDE integration. Configuring JRebel agent for the server is also quite straightforward. However, there are some exceptions to that. For instance, if you’d like to try JRebel on WebSphere AS and you are using MacOS, then you will have to take another route.

WebSphere Application Server is available for Linux and Windows platforms, but not for MacOS. The good news is that there is a WebSphere Docker image that you can use for development.

The developerWorks' article demonstrates it pretty clearly, what needs to be done in order to get WebSphere running in Docker and deploy a web application. With the help of the article I have assembled a demo project that deploys a Petclinic application on WebSphere running with JRebel in Docker container.

Let me explain some interesting bits of the outcome.

First of all, we need to derive from the base image, package the application archive into the new image, and make sure that WebSphere will deploy the application when it starts:

#Dockerfile
FROM ibmcom/websphere-traditional:profile
COPY target/petclinic.war /tmp/petclinic.war
RUN wsadmin.sh -lang jython -conntype NONE -c "AdminApp.install('/tmp/petclinic.war', \
'[ -appname petclinic -contextroot /petclinic -MapWebModToVH \
[[ petclinic petclinic.war,WEB-INF/web.xml default_host]]]')"

As you’ve noticed, it is not enough just to copy the application archive to some folder. You also need to invoke a script to actually deploy the application: call wsadmin.sh by providing it a snippet of Jython code.

Next, as we want to enable JRebel, we also need to package the agent binary into the image, and also we need to modify JVM arguments of the application server. Hence, the corresponding Dockerfile will get a little more complicated:

#Dockerfile
FROM ibmcom/websphere-traditional:profile
COPY ["jrebel-7.1.2","/tmp/jrebel"]
RUN wsadmin.sh -lang jython -conntype NONE -c "AdminConfig.modify(AdminConfig.list('JavaVirtualMachine', \
AdminConfig.list('Server')), [['genericJvmArguments', \
'-Xshareclasses:none -agentpath:/tmp/jrebel/lib/libjrebel64.so']])"
COPY target/petclinic.war /tmp/petclinic.war
RUN wsadmin.sh -lang jython -conntype NONE -c "AdminApp.install('/tmp/petclinic.war', \
'[ -appname petclinic -contextroot /petclinic -MapWebModToVH \
[[ petclinic petclinic.war,WEB-INF/web.xml default_host]]]')"


The Dockerfile above packages JRebel distribution into the image. That’s an easy part. The hard part was to figure out how to configure JVM arguments. In WebSphere, JVM arguments are set via server.xml configuration which is quite unusual. Normally, a developer would use an administrative user interface to modify the parameters, but in our case we need the arguments to be in the right place right at the start. Hence we need to do some Jython scripting via wsadmin again.

Now that the Dockerfile is ready, we can build and run the new image. In the terminal:

$ docker build -t waspet .
$ docker run -d -p 9043:9043 -p 9443:9443 -v `pwd`:/tmp/petclinic -v ~/.jrebel:/home/was/.jrebel waspet

The docker run command above also maps a few directories: a project folder and JRebel’s home folder. We map the project folder because JRebel agent could then see if any resource is updated. JRebel’s home folder (~/.jrebel) includes cached resources, so that if we would have to restart the Docker image then the application will start faster the next time.

Now it is possible to use JRebel to update the application instantly, without restarting the application server or redeploying the application. For the full list of instructions, see the README.md file in GitHub repository.








No comments:

Disqus for Code Impossible