Enterprise Java

Few maven tips and tricks

I was working on migrating an existing application that was using WebLogic Workshop (yes you read it right, using an IDE that is out of support) to maven. There were a few gotchas during the journey which i wanted to jot down here for anyone who might find it useful and specially for myself just as a reference.

The overall application was using Apache XMLBeans to deal with everything to do with XML and this was the first part I was migrating to maven. Maven did have a maven plugin for XMLBeans and the following snippet explains how you can incorporate this plugin to your project;

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<build>
    <plugins>
 
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>xmlbeans-maven-plugin</artifactId>
        <version>2.3.3</version>
  <configuration>
   <javaSource>1.5</javaSource>
   </configuration>
        <executions>
        <execution>
         <phase>generate-sources</phase>
            <goals>
              <goal>xmlbeans</goal>
            </goals>
        </execution>
         
       
        </executions>
      </plugin>
    </plugins>
  </build>

The one gotcha here is that you need to use the <javaSource>1.5</javaSource> tag if you want the XMLBeans code generated to have the “List” data structure for elements that have a maxoccurs set to unbounded. This is only if your code is already using the list type. Without this tag, this plugin will just generate the Array type for the unbounded elements.

Next up, it was the time to migrate the modules which exposed the web services of the application. As this was running on WebLogic, it used the “jwsc” task to generate the require artifact. I could not find an out of the box maven plugin which catered for this requirement and after some searching around I came across the solution where an ant build was invoked via the maven ant run plugin. Let us look at the configuration changes required on the pom.xml;

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<plugin>
      <groupId>org.codehaus.gmaven</groupId>
      <artifactId>gmaven-plugin</artifactId>
      <version>1.3</version>
      <executions>
        <execution>
          <id>set-main-artifact</id>
          <phase>package</phase>
          <goals>
            <goal>execute</goal>
          </goals>
          <configuration>
            <source>
              project.artifact.setFile(new File(project.build.directory+'/'+project.artifactId+'-'+project.version+'.war'))
            </source>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.6</version>
        <executions>
            <execution>
                <phase>prepare-package</phase>
                <configuration>
                    <target>
                        <property name="maven.compile.classpath" refid="maven.compile.classpath" />
                        <property name="maven.runtime.classpath" refid="maven.runtime.classpath" />
                        <property name="maven.test.classpath" refid="maven.test.classpath" />
                        <property name="maven.plugin.classpath" refid="maven.plugin.classpath" />
                        <ant antfile="src/main/ant/build.xml" target="all" />
                    </target>
                </configuration>
                <goals>
                    <goal>run</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>org.apache.ant</groupId>
                <artifactId>ant</artifactId>
                <version>1.7.1</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>ant-contrib</groupId>
                <artifactId>ant-contrib</artifactId>
                <version>1.0b2</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
   <groupId>weblogic</groupId>
   <artifactId>weblogic</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
   <dependency>
   <groupId>weblogic</groupId>
   <artifactId>xmlbeans</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
   <dependency>
   <groupId>weblogic</groupId>
   <artifactId>wlserv</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
   <dependency>
   <groupId>weblogic</groupId>
   <artifactId>jaxwsrt</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
   <dependency>
   <groupId>weblogic</groupId>
   <artifactId>beadescriptor</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>weblogic</groupId>
   <artifactId>beadescriptorbinding</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>weblogic</groupId>
   <artifactId>beadescriptorsettable</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>weblogic</groupId>
   <artifactId>staxb</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
   <dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
    <version>2.4.0</version>
  </dependency>
  <dependency>
   <groupId>weblogic</groupId>
   <artifactId>webservices</artifactId>
   <version>10.3.0</version>
   <scope>compile</scope>
  </dependency>
            <dependency>
                <groupId>com.sun</groupId>
                <artifactId>tools</artifactId>
                <version>1.5.0</version>
                <scope>system</scope>
                <systemPath>${java.home}/../lib/tools.jar</systemPath>
            </dependency>
        </dependencies>
    </plugin>
     
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <encoding>UTF-8</encoding>
            </configuration>
            
            <executions>
                  <execution>
                      <id>default-war</id>
                      <phase>none</phase>
                  </execution>
              </executions>
              
        </plugin>

Note that the dependency items with the groupId set with “weblogic” was installed on the maven repository manually using the maven install file command. The jar libraries required are as follows;

  • wlfullclient.jar (this jar was built as per the instructions specified here)
  • webserviceclient.jar
  • webservices.jar
  • wls-api.jar
  • xercesImpl.jar
  • xmlParserAPIs.jar
  • com.bea.core.descriptor.settable.binding_1.4.0.0.jar
  • com.bea.core.descriptor.wl.binding_1.1.0.0.jar
  • com.bea.core.descriptor.wl_1.1.0.0.jar
  • com.bea.core.xml.beaxmlbeans_1.0.0.0_2-4-0.jar
  • com.bea.core.xml.staxb.buildtime_1.3.0.0.jar
  • glassfish.jaxws.rt_2.1.3.jar

The next step is to drop the ant build.xml on to the src/main/ant directory of your project. The build.xml is as follows;

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<project name="build-webservice" default="all">
 
    <target name="all" depends="build.webService" />
 
    <path id="maven_plugin_classpath">
        <pathelement path="${maven.plugin.classpath}" />
    </path>
 
    <path id="maven_runtime_classpath">
        <pathelement path="${maven.compile.classpath}" />
        <pathelement path="${maven.runtime.classpath}" />
        <pathelement path="${maven.plugin.classpath}" />
        <pathelement path="${weblogic.jar}" />
    </path>
 
    <taskdef name="jwsc"
             classname="weblogic.wsee.tools.anttasks.JwscTask"
             classpath="${weblogic.jar}"
             classpathref="maven_plugin_classpath"
    />
 
    <target name="build.webService" description="Compile the web services if not up2date">
        <!--
            Eclipse compiles and places classes into target/classes when the workspace is building.
            If this folder exists when jwsc runs, then any classes that are already compiled will NOT
            be included in the final WAR file.  Thus, this directory is removed prior to created the
            webServices WAR fie.
        -->
        <delete dir="target/classes" />
        <jwsc srcdir="${project.build.sourceDirectory}"
              destDir="target"
              classpathref="maven_runtime_classpath"
              keepGenerated="yes"
              applicationxml="${project.build.directory}/application.xml"
              fork="true"
              memorymaximumsize="256m"
              verbose="true"
              debug="on"
        >
            <module contextPath="ws" name="${project.artifactId}-${project.version}">
                <jwsfileset srcdir=".">
                   <include name="**/*.java" />
                   <exclude name="**/*Test.java" />
                 </jwsfileset>
            </module>
        </jwsc>   
    </target>   
</project>

Note that there are no changes required to be made on this build.xml.

Next up, it was about building the EAR module to be deployed to weblogic. Looking at the EAR built up by WebLogic Workshop, I could see that all the required third-party libraries were being bundled up into a folder called APP-INF/lib which was located in the root directory of the EAR. Also the WAR files did not have any jar files in the lib directory and I wanted to mimic this functionality when building the EAR using maven. The following configuration allowed me to do that;

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<build>
  <finalName>ErrorXAEAR</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-ear-plugin</artifactId>
        <version>2.10.1</version>
        <configuration>
          <defaultLibBundleDir>APP-INF/lib/</defaultLibBundleDir>
          <skinnyWars>true</skinnyWars>
    <modules>
             <jarModule>
              <groupId>mtn.sa.errorxa</groupId>
       <artifactId>errorxa-ejb</artifactId>
               <bundleDir>/</bundleDir>
       <bundleFileName>ErrorXAEJB.jar</bundleFileName>
             </jarModule>
       <webModule>
               <groupId>mtn.sa.errorxa</groupId>
       <artifactId>errorxa-service</artifactId>
               <bundleDir>/</bundleDir>
       <bundleFileName>ErrorXAService.war</bundleFileName>
             </webModule>
          </modules>
        </configuration>
   
      </plugin>
    </plugins>
  </build>

The tag <skinnyWars> is what enables the lib directory of the war file not be populated with the third-party libraries required which is now bundled up in the APP-INF/lib directory on the EAR. The tag <defaultLibBundleDir> handles copying all required libraries to a folder called APP-INF/lib within the EAR.

One other thing with respect to the generation of the EAR is that I did not want maven to generate the application.xml file as this file along with the weblogic-application.xml was already generated on the project and I wanted use the same. To achieve this, all i had to do was to drop both those files into the folder src/main/application and the default application.xml was overridden.

I found the mvn dependency:tree tool of maven to be quite useful when building up the EAR to identify and remove the unnecessary dependencies being dragged into the EAR via recursive dependencies. With a simple exclusion tag I was able to remove the unwanted libraries.

That is about it for this post. I will keep updating the post with any things I may come across. The next step is to use maven to do the deploy and un-deploy of each application as part of the build process.

Reference: Few maven tips and tricks from our JCG partner Dinuka Arseculeratne at the My Journey Through IT blog.
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button