Friday, December 9, 2011

WebSphere 6.1 and NatJet

In this post, I will show how to deploy a simple NatJet Web application on WebSphere 6.1.

WebSphere is the IBM web app server. Version 6.1 is the first version to rely on Java 5 which is a minimum for NatJet. WebSphere uses its own Java runtime : IBM Java runtime. It is installed when installing WebSphere.

The IBM documentation says that WebSphere 6.1 supports Servlet 2.4. The default Servlet of a NatJet 4.0 project is 2.5. I have noticed that for some projects I got an error with the default NatJet project. I’ve needed to change the web.xml to have a 2.4 declaration and then it  has worked.

When writing this post, I was not anymore on the default Websphere 6.1 : I had added two feature packs : EJB 3.0 and WebService supports (it was a 6.1.0.13). I didn’t found anything on the documentation, but it seems that the feature packs add the support of Servlet 2.5, because I haven’t had any problem when writing this tutorial with a Servlet 2.5 declaration in the web.xml. This sound quite possible because one difference between 2.4 and 2.5 is the support of annotations and this is needed for EJB and WebServices.

NatJet 4.0 supports servlet specification 2.4 and plus. The 2.4 minimal request is due to Spring listener RequestContextListener, we rely on.

Complete JEE application servers like WebLogic and JBoss or WebSphere come with some additional libraries. By default, these jar libraries supersedes the ones delivered with your web app. I won’t go deeper on this point as it was not a problem with NatJet.

For this kind of server, security is a must and you must follow production standard : this means mainly in our case, two things :

  • deploying with a EAR
  • a database connections pool handled by the server.

NatJet with WebSphere

Deploying a NatJet application on a WebSphere server implies 2 additional tasks compare to deploying on Tomcat. These tasks are common tasks for deploying on WebSphere :

  • building an EAR file instead of a simple WAR
  • configuring the database pool

As we seen before some versions 6.1 of WebSphere supported only servlet 2.4. In this case we need adapting the web.xml to WebSphere with moving it back to 2.4.

I want this post to be a good starting point to somebody not really aware of WebSphere administration. As guiding someone through WebSphere administration is quite a long process, I will split the problem in two posts :

  • this post will describe
    • the basic NatJet project and its ant task
    • and deploying onto WebSphere 6.1
  • A second post that will describe the configuration of the database pool.

To allow you to follow me easily, I will create a very simple NatJet project : in this post, it will not use any database connection.

At the end of this post, I show you how to handle some problem you may encounter as changing the servlet specification of you web.xml.

Part I : Simple NatJet Web App

In this post, I will work with a very simple NatJet Web App without database connection. This part is mainly on NatJet .

Creating a simple NatJet Web App

I will go quickly to the essential, as I suppose you may already be familiar with some basics of NatJet.

In the NatJet Perspective, select in the File menu New –> NatJet Project Wizard.

  • The name of the new project will be NatJetWebSphere.
  • I let the target runtime as : Apache runtime
  • I change the Dynamic web version to 2.5. When doing so, the Configuration move to Custom instead of NatJet
  • I put back in Configuration, “NatJet v4.0 Project”

Press 3 times the button Next to get the “Configure NatJet Project” screen.

Select Custom Package root and enter the following indication :

  • Package root : fr.natsystem.demo.was
  • Main Module Name : NatJetWebSphere
  • Package name for the main Module : fr.natsystem.demo.was.ui

And then press the Finish button.

The project is created.

Creating Ant configuration

At this point, we want to deploy on WebSphere and we need to build a EAR file. We will do this using an ant task.

I already went through a quite complete post on using ant with NatJet : http://insidenatjet.blogspot.com/2010/11/using-ant-with-natjet.html. I will go quickly on this point.

We will work with a buildConfDir folder that will handle configuration files that may be specific to an environment.

We will store the application.xml file needed for a EAR in this folder.

We will then create the build.xml ant file and the build.properties. Inthis file we will add the ant task that generate the EAR file at the end.

Creating buildConfDir and application.xml

First we will create the new folder as root of our project.

Right click on the project node in the project explorer, and select New –> Other…. In the dialog box that popup, select the folder “General” and the node “Folder” and then press Next.

Enter “buildConfDir” as folder name and press Finish. The folder is created.

Then we will create the PRODapplication.xml file that will be used by the ant task.

Right click on the new “buildConfDir” node in the project explorer, and select New –> Other…. In the dialog box that popup, select the folder “XML” and the node “XML” and then press Next.

Enter “PRODapplication.xml” as file name and press Finish. The file is created and opened. As it has been opened with the wrong editor, close it and open it with the XML Editor.

Complete the file with the following code :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN" "http://java.sun.com/dtd/application_1_3.dtd">

   <application id="Application_ID">
      <display-name>NatJetWebSphere</display-name>
      <module id="WebModule_1">
         <web>
            <web-uri>NatJetWebSphere.war</web-uri>
            <context-root>/NatJetWebSphere</context-root>
         </web>
      </module>
   </application>

I put in bold, the part of the file that may need to be adapted to your configuration/project.

Creating build.properties

This file is created at the root level of the project

Right click on the project node in the project explorer, and select New –> Other…. In the dialog box that popup, select the folder “General” and the node “File” and then press Next.

Enter “build.properties” as file name and press Finish. The file is created and opened for editing. I click on the tab build.properties on the bottom of the editor to use the text editor

Complete the file with the following code :

project-name = NatJetWebSphere
tomcat-home = C:/NatJet4.0.0/thirdparty/apache-tomcat-6.0.29
builder=Nat System
#Specific environnement propeties
dtdLocation="../webapps/myProject/hibernate-configuration-3.0.dtd"

contextFile=contextProd.xml
#Contient les fichiers de configuration
buildConf-directory=buildConfDir

For explanation on this file refer to my post on ant with NatJet : http://insidenatjet.blogspot.com/2010/11/using-ant-with-natjet.html.

You may need to adapt the tomcat-home repository to the one available on you PC.

Creating build.xml ant file

This file is also created at the root level of the project

Right click on the project node in the project explorer, and select New –> Other…. In the dialog box that popup, select the folder “XML” and the node “XML” and then press Next.

Enter “build.xml” as file name and press Finish. The file is created and opened. As it has been opened with the wrong editor, close it and open it with the XML Editor.

Complete the file with the following code :

I put in bold the part that may be specific to the project or the standard configuration. These parts are :

  • the project name
  • the junit.package that will be excluded from compilation
  • the compile task were we force Java 1.5 as JDK to be compliant with WebSphere 6.1
  • the ant task at the end : this is the task that use the PRODapplication.xml file created before

<?xml version="1.0" encoding="UTF-8"?>
<project name="NatJetWebSphere" basedir="." default="war">

    <property file="build.properties" />

    <!-- Define Web Project Environnement -->
    <property name="source-directory"  value="src" />
    <property name="classes-directory"  value="build/classes" />
    <property name="web-directory"  value="WebContent" />
    <property name="war-file-name" value="${project-name}.war" />
    <property name="web-xml-file" value="${web-directory}/WEB-INF/web.xml" />
  
    <!-- Allow to exclude jUnit testcase—>
<property name="junit.package" value="fr/natsystem/demo/test/**" />

  
    <fail message="You need to specify contextFile property" unless="contextFile"/>
  
    <tstamp prefix="build-info">
        <format property="current-date" pattern="d-MMMM-yyyy" locale="fr" />
        <format property="current-time" pattern="hh:mm:ss a z" locale="fr" />
        <format property="year-month-day" pattern="yyyy-MM-dd" locale="fr" />
    </tstamp>
    <property name="build-directory" value="build" />

    <path id="project-classpath">
        <fileset dir="${web-directory}/WEB-INF/lib" includes="*.jar" />
        <fileset dir="${tomcat-home}/bin" includes="*.jar" />
        <fileset dir="${tomcat-home}/lib" includes="*.jar" />
    </path>

    <target name="clean">
        <delete dir="${classes-directory}" />
        <mkdir dir="${classes-directory}" />
    </target>

<target name="clean-context" description="Prepare files that needs to be modified depending on environment">
    <delete file="${source-directory}/hibernate.cfg.xml"/>
    <copy file="${source-directory}/hibernateAntMaster.cfg.xml" tofile="${source-directory}/hibernate.cfg.xml"/>      
</target>

<target name="copy-context-delivery" depends="clean-context" description="Task that updates files for the target environment">
    <replace file="${source-directory}/hibernate.cfg.xml" token="@@DTD-Declaration@@" value="${dtdLocation}"/>
    <delete file="${web-directory}/META-INF/context.xml"/>
    <copy file="${web-directory}/META-INF/${contextFile}" tofile="${web-directory}/META-INF/context.xml"/>
</target>
  
    <target name="copy-context-dev" depends="clean-context" description="Task to set the development environment, should be used to update modification of master files">
    <replace file="${source-directory}/hibernate.cfg.xml" token="@@DTD-Declaration@@" value="http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"/>
    <delete file="${web-directory}/META-INF/context.xml"/>
    <copy file="${web-directory}/META-INF/contextDev.xml" tofile="${web-directory}/META-INF/context.xml"/>

    </target>
  
    <target name="copy-non-java-files">
        <copy todir="${classes-directory}" includeemptydirs="false">
            <fileset dir="${source-directory}" excludes="**/*.java" />
        </copy>
    </target>

   <!-- Pour WAS java 1.5 -->
    <target name="compile" depends="clean,copy-non-java-files">
        <echo>jUnit Package ${junit.package}</echo>
        <javac srcdir="${source-directory}" destdir="${classes-directory}"
        classpathref="project-classpath"
               compiler="javac1.5"
            source="1.5"
            target="1.5"
        excludes="${junit.package}"/>
    </target>

    <target name="war" depends="compile">
        <mkdir dir="${build-directory}/bin" />
        <delete file="${build-directory}/bin/${war-file-name}" />
        <war warfile="${build-directory}/bin/${war-file-name}" webxml="${web-xml-file}">
            <classes dir="${classes-directory}" />
          
            <fileset dir="${web-directory}">
                <!-- Need to exclude it since webxml is an attribute of the war tag above -->
                <exclude name="WEB-INF/web.xml" />
                <!-- Exclude NatJet xml files for the description of panels -->
                <exclude name="resources/**" />
                <excludesfile/>
            </fileset>
            <manifest>
                <attribute name="Built-By" value="${builder}" />
                <attribute name="Built-On" value="${build-info.current-date}" />
                <attribute name="Built-At" value="${build-info.current-time}" />
            </manifest>
        </war>
    </target>
   
    <!-- CREATION DU binaire EAR de PROD -->
    <target name="ear-PROD" depends="war"
        description="création du fichier EAR de Production de l'application">
        <ear destfile="${build-directory}/bin/${project-name}.ear" appxml="${basedir}/${buildConf-directory}/PRODapplication.xml">
            <fileset dir="${build-directory}/bin" includes="${war-file-name}"/>
            <manifest>
                <attribute name="Environment" value="PROD" />
                <attribute name="Built-By" value="${builder}" />
                <attribute name="Built-On" value="${build-info.current-date}" />
                <attribute name="Built-At" value="${build-info.current-time}" />
            </manifest>
        </ear>
    </target>
   

</project>

For explanation on this file refer to my post on ant with NatJet : http://insidenatjet.blogspot.com/2010/11/using-ant-with-natjet.html.

In this version, we rely on a buildConfDir where we store the configuration file : in my previous post we store the file directly in the project. The approach in this post is better as we do not deliver configuration file from other environments.

All the files used by this ant file are not available at this point of the project.

Fixing Java files

If we try to build the project with ant, we may have the following error fro 6 java files :

src\fr\natsystem\demo\was\NatJetWebSphere.java:6: package fr.natsystem.resource.localization.NatJetWebSphere does not exist
[javac] import fr.natsystem.resource.localization.NatJetWebSphere.*;

We are going to fix these errors.

Before starting, we need to rebuild with Eclipse our project : the ant task has deleted all class files. Thus a lot of your Java class may shows up in error (already or at the first save you will do).

  1. To fix this point, go to menu “Project” and select menu item “Clean…”
  2. Select your project : and press OK. This will rebuild the project.

If you do not do this after an incorrect ant build, you will have plenty of errors in your project as the class files have been deleted.

Then for each of the files with the error, you edit the file and do an “Organize imports” (Crt Shift O) and save it. This will delete from the Java class the import to an empty package.

Then you can rebuild using ant. This time, you should get the following output

Buildfile: C:\Users\jltho.NATSYSTEM\Documents\wksp400\NatJetWebSphere\build.xml
clean:
   [delete] Deleting directory C:\Users\jltho.NATSYSTEM\Documents\wksp400\NatJetWebSphere\build\classes
    [mkdir] Created dir: C:\Users\jltho.NATSYSTEM\Documents\wksp400\NatJetWebSphere\build\classes
copy-non-java-files:
     [copy] Copying 12 files to C:\Users\jltho.NATSYSTEM\Documents\wksp400\NatJetWebSphere\build\classes
compile:
     [echo] jUnit Package fr/natsystem/demo/test/**
    [javac] Compiling 12 source files to C:\Users\jltho.NATSYSTEM\Documents\wksp400\NatJetWebSphere\build\classes
    [javac] Note: Some input files use or override a deprecated API.
    [javac] Note: Recompile with -Xlint:deprecation for details.
war:
    [mkdir] Created dir: C:\Users\jltho.NATSYSTEM\Documents\wksp400\NatJetWebSphere\build\bin
      [war] Building war: C:\Users\jltho.NATSYSTEM\Documents\wksp400\NatJetWebSphere\build\bin\NatJetWebSphere.war
ear-PROD:
      [ear] Building ear: C:\Users\jltho.NATSYSTEM\Documents\wksp400\NatJetWebSphere\build\bin\NatJetWebSphere.ear
BUILD SUCCESSFUL
Total time: 10 seconds

If you do a refresh of the project (F5) you should now see in build/bin the file NatJetWebSphere.ear.

 

Part II : Deploying on WebSphere 6.1

Your server should be started.

To know if it is started you can try to connect to the administrative console : https://localhost:9043/ibm/console/logon.jsp

If you got the login form, the server is started.

If this is not the case go to your Windows menu : “Tous les programmes” –> “IBM Websphere” –> “Application Server V6.1” –> Profils –> AppSrv01 –> “Démarrer le serveur”.

Connect to the administrative console : https://localhost:9043/ibm/console/logon.jsp

You will need a login account. Then select in “Applications” the link : “Installation d’une nouvelle application” (sorry but my web console is in French).

NJWAS01installed

In the next page, using the Browse button to select your EAR.

NJWAS02installedSelectEAR

And then press Next/Suivant button. You should got after a few seconds, the following page :

NJWAS03installedOption

Just press Next/Suivant on this first step.

After a while you should get the mapping page (step 2) :

NJWAS04installedMapping

Just press Next/Suivant, you should get the page (step 3) :

NJWAS05installedStep3

Just press Next/Suivant, to get the summary page

NJWAS06installedStep4SUmmary

Then press Terminate/Terminer. You have to wait several long seconds before to get the result.

Then press Save and go to start the application.

You should get on the top of the application page after a while :

NJWAS07Started

Testing

At this point you should be able to display your web app in the browser at the following URL : http://localhost:9080/NatJetWebSphere

It should display the standard page of a new NatJet project.

 

Problems you may encounter

Servlet 2.5 does not work

If your WebSphere 6.1 is really the basic version, it may not support servlet 2.5. In this case, you need to change your web.xml file.

If you don’t you wil get an error message when deploying or starting the web  app.

To fix your problem, you need to edit the WebContent/WEB-INF/web.xml file, and change the web-app declaration tag of your XML file.

You should have now the following code :

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_ID" version="2.4"
    xmlns="
http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>NatJetWebSphere</display-name>
    <servlet>
        <servlet-name>WebContainerSpringServletNS</servlet-name>
        <servlet-class>
            fr.natsystem.natjet.echo2.webcontainer.WebContainerSpringServletNS</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>WebContainerSpringServletNS</servlet-name>
        <url-pattern>/app</url-pattern>
    </servlet-mapping>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    <session-config>
        <session-timeout>5</session-timeout>
    </session-config>
</web-app>

This point should fix your problem. This is the way to move back a NatJet web app to a servlet 2.4 container.

 

Deploying EAR on WebSphere doesn’t finish

Sometimes deploying on WebSpshere 6.1, I get stuck on the following items (action SEJ0400I) :

ADMA5005I: L'application NatJetWebSphere est configuré dans le référentiel WebSphere Application Server.

SECJ0400I: La mise à jour de l'application NatJetWebSphere avec les informations appContextIDForSecurity information a abouti.

 

 
When I get this, I first wait one or two minutes as this task can be long, and the if nothing change I click on the link “application entreprise” on the left panel. The new page have a warning message on the top :
 
NJWAS08Blocked
 
Click on the link “Save/Sauvegarder”.
Then I can start your web app.
 
This work around help me a lot when working on WebSphere 6.1. I’m not a WebSphere admin and I didn’t have time to understand what was going on, but the trick does the job.
 

Conclusion

We’ve seen how to deploy a simple NatJet applications on WebSphere 6.1 and how to handle some little problems.

In this post you have a complete build.xml sample that will help you build a EAR with ant from a NatJet project.

Deploying a NatJet web app that used a database connection (if you are using the server database connection pool) may be a bit more complicated (due to WebSphere). I will try to write soon a post on this subject.

No comments:

Post a Comment