Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

Here is a very simple build system that compiles and packages a web service defined as a JWS file. The web service is packaged as an EAR file and is deployed to WebLogic (12c in my case).

Below is the directory structure that's required to get started. The lib directory holds all of the required WebLogic jar files, the src directory contains the source code. It is possible to point the build system to your local WebLogic install by changing the wlslibs path in the build-base.xml file; personally I like to have these in a separate directory and to have just the JARs that I need. The build and dist directories are not strictly required as they are created during build. The final EAR file will be in the dist directory.
 Directory Structure
|-- build/
|-- dist/
|-- lib/
| |-- wlfullclient.jar
| |-- com.bea.core.beangen_2.1.0.0.jar
| |-- com.bea.core.descriptor.settable.binding_2.1.0.0.jar
| |-- com.bea.core.xml.xmlbeans_2.4.0.0_2-5-1.jar
| |-- com.oracle.webservices.wls.jaxrpc-client_12.1.2.jar
| |-- com.oracle.webservices.wls.jaxws-wlswss-client_12.1.2.jar
| |-- com.oracle.webservices.wls.wls-ws-api_2.0.0.0.jar
| +-- weblogic-classes.jar
|-- src/
| +-- net/
| +-- igorkromin/
| +-- WsExampleImpl.java
|-- build-base.xml
|-- build.properties
+-- build.xml


I define all of the properties in a separate properties file. This specifies the WLS admin URL, target server, username and password, the directory locations and the web service details such as its name, context path, the JWS source file and whether to keep the generated Java source code or not. Since jwsc is used, the serviceURI is set to the value of serviceName attribute on the @WebService annotation and hence not defined here.
 build.properties
# WLS details
wls.adminurl=t3://localhost:7001
wls.targets=AdminServer
wls.user=weblogic
wls.passwd=changeit
# Directories
libs.dir=lib
build.dir=build
dist.dir=dist
src.dir=src
# WS details
ws.name=WsExample
ws.context=wsexample
ws.jwsfile=net/igorkromin/WsExampleImpl.java
ws.keepgenerated=yes




The following file is used to create the WebLogic classpath and to define the jwsc and wldeploy tasks. It also loads the properties file. I find it more logical to separate this into a different build file, although it can be included in the main build.xml file if preferred. This build file cannot be used on its own, so the default target fails the build if it's invoked directly.
 build-base.xml
<?xml version="1.0" encoding="UTF-8" ?>
<project default="build-fail">
<property file="build.properties"/>
<!-- WLS jar files -->
<path id="wlslibs">
<fileset dir="${libs.dir}">
<include name="**/*.jar"/>
</fileset>
</path>
<!-- WLS task definitions -->
<taskdef
name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask"
classpathref="wlslibs"
/>
<taskdef
name="wldeploy"
classname="weblogic.ant.taskdefs.management.WLDeploy"
classpathref="wlslibs"
/>
<target name="build-fail">
<fail message="Do not use this build file directly"/>
</target>
</project>


This is the main build.xml file, it imports the build-base.xml and defines all of the required targets. The default target is 'all', which will clean, build and deploy the web service. The build-service target uses jwsc to compile the JWS file and package it into a WAR file. This is followed by packaging it into an EAR file ready for deployment. The deploy-service target will attempt to undeploy the web service first (no failure on error) and then to deploy it.
 build.xml
<?xml version="1.0" encoding="utf-8"?>
<project default="all">
<import file="build-base.xml"/>
<target name="all" depends="clean,build-service,deploy-service"/>
<target name="init">
<mkdir dir="${build.dir}"/>
<mkdir dir="${dist.dir}"/>
</target>
<target name="clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<target name="build-service" depends="init">
<!-- Build WAR file using jwsc -->
<jwsc
srcdir="${src.dir}"
destdir="${build.dir}"
keepgenerated="${ws.keepgenerated}"
classpathref="wlslibs"
>
<module
name="${ws.name}"
contextpath="${ws.context}"
explode="false"
>
<jws
file="${ws.jwsfile}"
type="JAXWS"
/>
</module>
</jwsc>
<!-- Package into EAR file -->
<ear
destfile="${dist.dir}/${ws.name}.ear"
appxml="${build.dir}/META-INF/application.xml"
>
<fileset file="${build.dir}/${ws.name}.war"/>
<metainf
dir="${build.dir}/META-INF"
excludes="application.xml"
/>
</ear>
</target>
<target name="deploy-service" depends="build-service">
<!-- Try to undeploy the WS first -->
<wldeploy
action="undeploy"
failonerror="false"
name="${ws.name}"
adminurl="${wls.adminurl}"
targets="${wls.targets}"
user="${wls.user}"
password="${wls.passwd}"
/>
<!-- Deploy WS -->
<wldeploy
action="deploy"
failonerror="true"
library="false"
upload="true"
remote="true"
name="${ws.name}"
source="${dist.dir}/${ws.name}.ear"
adminurl="${wls.adminurl}"
targets="${wls.targets}"
user="${wls.user}"
password="${wls.passwd}"
/>
</target>
</project>


That's all there is to it, this doesn't show how to add additional deployment descriptors to the build or how to package extra libraries, that will be covered in other blog posts in the future.

-i

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.