Automation of IIB Maven and Ant

I have been working on a project with IIB (IBM Integration Bus). If you are like me, you want to automate all those pesky build tasks. In IIB, I needed to package and build my project (BAR).

I investigated scripting the build using the mqsipackagebar command . I noticed at the bottom a description of using it with ANT.

I’ve used ANT in a few projects (in combination with Maven). I took the script as a starting point, added the jar files and property files (based on configuring environments without IIB). I configured the maven-antrun-plugin in order to integrate within my parent project’s maven build.

Here is some sample code for you, I hope it helps you all get started:

Localized Maven Repositories – A Hot Tip

I’ve been building a Maven Project that uses some jar files which are not in Maven Central (or any repository). I ran across this article – Local Maven Dependencies. I found it very helpful.

Simply, do the following:

create a directory (d:/folder/repo)

Run a maven deploy to url (it’ll create the repository details based on the flags)

mvn deploy:deploy-file -Durl=file://d:/folder/repo/ -Dfile=Common.jar -DgroupId=xyz -DartifactId=Common -Dpackaging=jar -Dversion=1.0

and add to your Maven Project’s POM
<repository>
<id>Local Repository</id>
<name>project</name>
<url>file:${project.basedir}/../mylibrary.project/src/repo</url>
</repository>

Then reference your jar file with a new dependency.

The code should almost write itself from there 🙂

Maven Tips

Here are some tips for Maven Java Projects in Eclipse.

#1 If you pom.xml is missing maven-compiler-plugin, Eclipse (when you do Maven > Update Project), defaults the compiler level for the project to 1.5.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>

Now, it gets even more tricky… if your project has defined features that are from Java 1.6, 1.7 or 1.8

#2 if you your web.xml defines a version not compatible with a project facet you depend on, you get a lot of problems/errors

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

Convert the web.xml to 3.1, and compatibility should now be fixed

<web-app id="WebApp_ID" version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

I found this stackoverflow entry helpful and this one.

#3 Update > Maven Project overwrites manual changes to #1/#2.

I found this stackoverflow entry helpful.

#4 Make sure you don’t have two web.xml files… the convert dynamic web project to maven project does some funky stuff.

My Experience with maven-antrun-plugin

I’ve been spending some time with maven so that files which matched a certain criteria were automatically moved in the project – OpenNTF SocialSDK.  The files only should be moved when the files don’t have -SNAPSHOT at the end of the version.

I started modifying some code that used maven-antrun-plugin, which bridges the maven-ant worlds.  I tried mixing complex conditional depends on and unless statements from Ant targets and Ant Tasks. Where the target “depends” on another target, you should be able to conditionally execute a target.  I wrote the code, however it never ran cleanly, always throwing an error.

I split the ant tasks and targets into a separate file, and the code now runs cleanly.  From the best practices I’ve read it’s better to pick one, and only use one Maven file or Ant file, I however couldn’t get it to read depends on targets.

I hope you find this ant-maven hack as helpful as I did.

 

The solution is found in the commit – added support for automatically moving the cdnjs files when a release.

My Introduction to Liberty and WebSockets

Recently, I’ve been turned on to IBM WebSphere Libertysuper fast and highly configurable Application Server Runtime.  The runtime requires Java 7.0 to get access to the latest features to build web applications, OSGi applications and EJBs.

Two features caught my eye were Java Servlet 3.1 and Java API for WebSocket 1.0.  The WebSocket component (JSR356) in combination with the Servlet 3.1 component offer a super foundation for realtime web applications.  The WebSocket is superbly interesting as it’s “full duplex, long-lived” (per the blog).   Make that 3 features, I forgot the JSON-P feature

I just had to play around and investigate the websockets component. I setup the Eclipse environment with the WebSphere Liberty Profile. I then setup a Maven Project for Liberty.

Click File > New Maven Project
Select Use Default Workspace Location
Click Next
Select the http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/maven/repository Catalog
Select the com.ibm.tools.archetype webapp-jee7-liberty
Click Next

Maven Achetype
Maven Achetype

Enter a Group Id: com.ibm.ess.appdev.liberty
Enter a Artifact Id: demo
Enter Package: com.ibm.ess.appdev.liberty
Click Finish

Archetype Parameters
Archetype Parameters

If you find an error after creating the project, such as:

ArtifactDescriptorException: Failed to read artifact descriptor for com.ibm.tools.target:was-liberty:pom:LATEST: VersionResolutionException: Failed to resolve version for com.ibm.tools.target:was-liberty:pom:LATEST: Could not find metadata com.ibm.tools.target:was-liberty/maven-metadata.xml in local (/Users/paulbastide/.m2/repository)
pom.xml error
pom.xml error

Open the pom.xml
Copy the following snippet to the pom.xml
Click Save

 <repositories>
 <repository>
 <id>maven online</id>
 <name>maven repository</name>
 <url>https://repo1.maven.org/maven2/</url>
 </repository>
 <repository>
 <id>liberty maven online</id>
 <name>liberty maven repository</name>
 <url>http://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/maven/repository/</url>
 </repository>
 </repositories>

Right Click on the demo project, and go to Run As -> Run on Server

Select Manually define a new server
Expand IBM
Select WebSphere Application Server Liberty Profile
18015657

Click Next
Select Install from an archive or a repository
Leave the default JRE selected
Click Next

Runtime Environment
Runtime Environment

Enter a Destination Path, such as /Users/paulbastide/Desktop/liberty
Select Download and Install a New Runtime Environment from Liberty Repository
Select Liberty Profile Beta Runtime
Click Next

Install the Runtime
Install the Runtime

Click Next

Select I accept the terms of all the license agreements

Click Next

Leave the defaults
Click Next

You should see demo under configured
Click Finish (It could take a few minutes to download the entire profile)

Once complete you’ll see the notice that it was installed successfully.

Success
Success

Let’s setup the server part.

Click on the Servers tab
Expand WebSphere Application Server Liberty Profile at localhost
Double Click on Server Configuration

Configuration
Configuration

Click Source
Add Children to the Feature Manager
<feature>servlet-3.1</feature>
<feature>websocket-1.0</feature>

Feature Manager
Feature Manager

Click File > Save

The server is setup to host our WebSockets.

Expand Java Resources > src/main/java > com.ibm.ess.appdev.liberty
Right Click the Package
Create a new Java Class (extending java.lang.object) – DemoEndpoint.java

Add the Framework for the Annotations

 @ServerEndpoint sets the path at which the websocket is hosted, and can contain a macro/text replacement like common JAX-RS code
 @OnOpen - start of the session
 @OnMessage - when there is a message in the session
 @OnClose - when the session is closed
 @OnError - when there is an error related to the ongoing session
 @ServerEndpoint(value = "/DemoEndpoint/{channel}")
 public class DemoEndpoint {
@OnOpen
 public void open(Session session, @PathParam("channel") String channel) {
}
@OnMessage
 public String message(String message, Session session, @PathParam("channel") String channel) {
 String result = "";
return result;
 }
@OnClose
 public void close(Session session, CloseReason reason) {
}
@OnError
 public void error(Throwable t) {
 t.printStackTrace();
 }
 }

I’m not going to extend open/error or close, and just going to focus on the message part.

Let’s do a simple channel based echoing.

Replace the method – message with the following java

 String result = "" + channel + " " + message;
 System.out.println("Message: " + message);
 return result;

Expand src > webapp
Right Click on webapp
Create a new HTML Page – demo.html

Replace the HTML page with the following Content

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>Insert title here</title>
 <script type="text/javascript">
 var socket = new WebSocket("ws://localhost:9080/demo/DemoEndpoint/vampire");
function sendMessage(){
 socket.send("example data");
 }
socket.onmessage = function (event) {
 document.getElementById('content').innerHTML = document.getElementById('content').innerHTML
 + "<br/>"
 + event.data;
 }
</script>
 </head>
 <body>
 <button onClick="javascript:sendMessage()">Send Sample Content to Channel
 </button>
 <div id="content">
 </div>
 </body>
 </html>

Navigate to http://localhost:9080/demo/demo.html
Click Send Sample Content to Channel

Demo
Demo

I plan on playing around with the code more, and see what I can really do with WebSockets, they offer a lot of potential (specifically with Handlers).

I am going to have to play around with error handling and sending messages across multiple sessions/users/authentication.

Some good reference articles are:

WebSphere Liberty – WebSockets Maven and WebSphere WebSocket Sample
WASDev Planning Poker WebSockets Sample WebSockets Overview WebSockets Overview From Mozilla
StackOverflow Maven Repositories Question Derby WebSockets Java Code
Configure Liberty Profile WebSockets and Liberty Overview WebSocket Cookbook