Wednesday, November 18, 2009

The Goods Delivered – SOA Suite “ant-sca-compile.xml” File Simplified (Plus Ivy Dependency Management)

As promised in my last post, I’ve been continuing to work on getting Oracle SOA Suite (11g) projects to build outside the JDeveloper IDE.  I’ve spent some time getting the ant-sca-compile.xml file to work first and thought I’d share the results.

I’ve rushed a little to publish this so there are still a few things you’ll have to do manually if you want this to work for you, but it does work. Trust me.  If I get a chance, I’ll keep blogging things as I progress and hopefully you’ll have to do less and less work if you want to do the same as us.

What I have now comes in three parts:

1. A simplified ant-sca-compile.xml file

<?xml version="1.0" encoding="iso-8859-1"?>
<project xmlns:ivy="antlib:org.apache.ivy.ant"
         name="ant-scac"
         default="scac">

    <!-- Set all the Properties we need -->
    <property file="build.properties"/>
    <!--propertycopy name="proj.revision" from="${project}.revision"/-->
    <property name="oracle.home" value="${applications.home}/lib"/> <!-- Monkey patch to remove need for full JDeveloper install -->
    <property name="config.dir" value="C:/oracle/Middleware/jdeveloper/integration/seed/soa/configuration/" />  
    <property name="compositeDir" value="${applications.home}/${compositeName}" />
    <property name="scac.input" value="${compositeDir}/composite.xml"/>
    <condition property="scac.displayLevel" value="3">
        <not>
            <isset property="scac.displayLevel"/>
        </not>
    </condition>
    <condition property="scac.overwrite" value="true">
        <not>
            <isset property="scac.overwrite"/>
        </not>
    </condition>
    <condition property="scac.error" value="${tmp.output.dir}/${compositeName}.error">
        <not>
            <isset property="scac.error"/>
        </not>
    </condition>
    <condition property="scac.output" value="${tmp.output.dir}/${compositeName}.xml" >
        <not>
            <isset property="scac.output"/>
        </not>
    </condition>
    <condition property="scac.sar" value="${tmp.output.dir}/${compositeName}.sar" > 
        <not>
            <isset property="scac.sar"/>
        </not>
    </condition>
    <condition property="scac.plan" value="${tmp.output.dir}/${compositeName}.plan" >
        <not>
            <isset property="scac.plan"/>
        </not>
    </condition>

    <!-- Set the Path we need for the Ant Taskdefs -->
    <property name="oracle.ant.taskdef.path" refid="oracle.ant.taskdef.path"/>
    <path id="oracle.ant.taskdef.path">
        <fileset dir="${applications.home}/lib">
            <include name="fabric-runtime.jar"/>
            <include name="soa-infra-mgmt.jar"/>
            <include name="soa-infra-tools.jar"/>
        </fileset>
    </path>

    <!-- Oracle SOA Suite Project Compilation Targets -->
    <target name="generateplanfromsar" description="Generate soa config plan from a soa archive">
        <ivy:resolve />
        <generateplan sar="${scac.sar}"
                      planfile="${scac.plan}"
                      verbose="true"
                      overwrite="${scac.overwrite}"/>
    </target>

    <target name="generateplan" description="Generate soa config plan from a composite">
        <ivy:resolve />
        <generateplan composite="${scac.input}"
                      planfile="${scac.plan}"
                      verbose="true"
                      overwrite="${scac.overwrite}"/>
    </target>
    <target name="attachplan" description="Attach a soa config plan to a soa archive">
        <ivy:resolve />
        <attachplan planfile="${scac.plan}"
                    sar="${scac.sar}"
                    verbose="true"
                    overwrite="${scac.overwrite}"/>
    </target>

    <target name="extractplan" description="Extract a soa config plan from a soa archive">
        <ivy:resolve />
        <extractplan planfile="${scac.plan}"
                     sar="${scac.sar}"
                     verbose="true"
                     overwrite="${scac.overwrite}"/>
    </target>

    <target name="validateplanfromsar" description="Validate a soa config plan for a soa archive">
        <ivy:resolve />
        <validateplan sar="${scac.sar}"
                      planfile="${scac.plan}"
                      reportfile="${scac.output}"
                      verbose="true"
                      overwrite="${scac.overwrite}"/>
    </target>

    <target name="validateplan" description="Validate a soa config plan for a composite">
        <ivy:resolve />
        <validateplan composite="${scac.input}"
                      planfile="${scac.plan}"
                      reportfile="${scac.output}"
                      verbose="true"
                      overwrite="${scac.overwrite}"/>
    </target>
    <target name="scac" description="Compile and validate a composite" depends="init">
        <property name="scac.tasks.class.path" refid="scac.tasks.class.path"/>
        <scac input="${scac.input}"
              outXml="${scac.output}"
              error="${scac.error}"
              appHome="${compositeDir}"
              failonerror="true"
              displayLevel="${scac.displayLevel}">
        </scac>
    </target>

    <target name="init" description="Sets up the compilation classpath">
        <property name="ivy.local.default.root" value="C:/Documents and Settings/aharmel/.m2/repository" />
        <property name="ivy.local.default.artifact.pattern" value="[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
        <ivy:resolve />
        <ivy:cachepath conf="compile" pathid="scac.tasks.class.path" />
    </target>

    <!-- taskdefs mapping script Ant targets to Oracle Ant implementataion classes -->
    <taskdef name="scac" classname="oracle.soa.scac.scac" classpath="${oracle.ant.taskdef.path}" />
    <taskdef name="attachplan" classname="oracle.soa.deployplan.task.attachPlan" classpath="${oracle.ant.taskdef.path}" />
    <taskdef name="extractplan" classname="oracle.soa.deployplan.task.extractPlan" classpath="${oracle.ant.taskdef.path}" />
    <taskdef name="generateplan" classname="oracle.soa.deployplan.task.generatePlan" classpath="${oracle.ant.taskdef.path}" />
    <taskdef name="validateplan" classname="oracle.soa.deployplan.task.reportPlan" classpath="${oracle.ant.taskdef.path}" />
</project>

NOTE: I haven’t yet figured out how to get Ivy to manage the three dependencies for the  Oracle Ant Tasks themselves. I’ll update later once I have time to fix this.  Until then you also need to copy the three required jars into a new “lib” directory in your Composite Project

NOTE: The Monkey patch requires that you create a new “lib” directory in your Composite Project and add “./soa/modules/oracle.soa.bpel_11.1.1/orabpel.jar” to it. You’ll find this in your JDeveloper install

2. Dependencies managed in a new ivy.xml file

<ivy-module version="2.0">
    <info organisation="copfs" module="cmrs-dummy" />

    <configurations>
        <conf name="base" description="JARs required at both compile and runtime" />
        <conf name="taskdefs" description="JARs required for Ant Taskdefs" />
        <conf name="compile" description="JARs required at compile time" />
        <conf name="runtime" description="JARs required at runtime" />
    </configurations>

    <dependencies>
        <dependency org="oracle.soa.bpel" name="orabpel" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.soa.bpel" name="orabpel-validator" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.soa.bpel" name="orabpel-common" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.soa.bpel" name="orabpel-thirdparty" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.soa.fabric" name="fabric-runtime" rev="11.1.1" conf="compile,taskdefs->default" />
        <dependency org="oracle.soa.mgmt" name="soa-infra-mgmt" rev="11.1.1" conf="compile,taskdefs->default" />
        <dependency org="oracle.soa.fabric" name="soa-infra-tools" rev="11.1.1" conf="compile,taskdefs->default" />
        <dependency org="oracle.soa.fabric" name="testfwk-xbeans" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.fabriccommon" name="fabric-common" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.fabriccommon" name="fabric-common" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.xdk" name="xmlparserv2" rev="11.1.0" conf="compile->default" />
        <dependency org="commons-logging" name="commons-logging" rev="1.0.4" conf="compile->default" />
        <dependency org="commons-digester" name="commons-digester" rev="1.7" conf="compile->default" />
        <dependency org="oracle.commonj-sdo" name="commonj-sdo" rev="2.1.0" conf="compile->default" /> <!-- This is a hack as the Oracle JDeveloper one is different from the one in M2 repositories -->
        <dependency org="oracle.logging-utils" name="oracle.logging-utils" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.dms" name="dms" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.webservices" name="orawsdl" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.mds" name="mdsrt" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.jmx" name="jmxframework" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.adf.share" name="adf-share-base" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.adf.share" name="adf-logging-handler" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.odl" name="ojdl" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.http-client" name="oracle-httpclient" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.wsm.common" name="wsm-policy-core" rev="11.1.1" conf="compile->default" />
        <dependency org="oracle.classloader" name="oracle-classloader" rev="11.1.1" conf="compile->default" />
        <dependency org="com.bea.core" name="com-bea-core-apache-commons-lang" rev="2.1.0" conf="compile->default" />
        <dependency org="com.bea.core" name="com-bea-core-xml-xmlbeans" rev="2.2.0.0" conf="compile->default" />
    </dependencies>
</ivy-module>

NOTE: These are only the dependencies for the “scac” target. More may be required for the other targets.

NOTE: I used a local maven 2 repository as my Ivy repository. I had to import the JARs which came with JDeveloper into this in the structure indicated by the “dependency” entries.  The aim was to keep things structured nicely, add version info to JARs which lacked this.

NOTE: I tried to reuse standard external JARs from the various M2 repositories where possible. In the case of the com-bea-core libraries and oracle.commonj-sdo library this was not possible.  It seems for example that the latter has an additional package added to it (“helper”) even though the version number and name of this JAR is the same as you find on the web.

3. A Pared-down build-properties file

# temp
tmp.output.dir=c:/

# Project
applications.home=C:/Jazz/MyWorkspace-16-09-2009/WpfAutoDeployTestApp/TestApplication/
compositeName=GetEmployeeName
revision=1.0

deployment.plan.environment=dev

# dev deployment server weblogic
bea.home=C:/oracle/Middleware
dev.serverURL=
http://10.23.7.66:8001
dev.overwrite=true
dev.user=weblogic
dev.password=welcome1
dev.forceDefault=true

# acceptance deployment server weblogic
# acc.serverURL=
http://10.23.7.66:8001
# acc.overwrite=true
# acc.user=weblogic
# acc.password=welcome1
# acc.forceDefault=true

NOTE: See, the #global properties are gone. Nice eh?

NOTE: You’ll need to set the applications.home yourself as applicable. Not the nicest I know, but I’m moving fast here…

NOTE: I’ve hacked things so I need to provide the compositeName. This is not how it worked out of the box, and you could fix it to get this from your [App Name].properties file

No comments: