Ant task to convert WSDL to POJO with the use of XJC gives an Error package name - ant

I have an Ant task that takes a wsdl file and should auto generate POJO's (client side Java) , so I can start programming my client side JAX-WS web services.
However I'm getting an error "[ERROR] The package name .... used for this schema is not a valid package name"
This error only occurs when my wsdl file has more than 1 schema import in it such as
<xsd:import namespace="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry/Response" schemaLocation="ProcessCustomerInquiryResponse.xsd"/>
<xsd:import namespace="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry/Request" schemaLocation="ProcessCustomerInquiryRequest.xsd"/>
</xsd:schema>
Below is the entire wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:CMSLINK="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry" xmlns:REQ="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry/Request" xmlns:RESP="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry/Response" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry" name="ProcessCustomerInquiryService">
<wsdl:types>
<xsd:schema>
<xsd:import namespace="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry/Response" schemaLocation="ProcessCustomerInquiryResponse.xsd"/>
<xsd:import namespace="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry/Request" schemaLocation="ProcessCustomerInquiryRequest.xsd"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="ProcessCustomerInquiryRequest">
<wsdl:part name="requestData" element="REQ:ProcessCustomerInquiryRequest"/>
</wsdl:message>
<wsdl:message name="ProcessCustomerInquiryResponse">
<wsdl:part name="responseData" element="RESP:ProcessCustomerInquiryResponse"/>
</wsdl:message>
<wsdl:portType name="ESB_ProcessCustomerInquiryService">
<wsdl:operation name="ReqResp">
<wsdl:input name="processRequest" message="CMSLINK:ProcessCustomerInquiryRequest"/>
<wsdl:output name="processResponse" message="CMSLINK:ProcessCustomerInquiryResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ProcessCustomerInquiryServiceSoapBinding" type="CMSLINK:ESB_ProcessCustomerInquiryService">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="ReqResp">
<wsdlsoap:operation soapAction="process"/>
<wsdl:input>
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ProcessCustomerInquiryService">
<wsdl:port name="ProcessCustomerInquiry" binding="CMSLINK:ProcessCustomerInquiryServiceSoapBinding">
<wsdlsoap:address location="http://tsesbd01.tms.toyota.com:51180/v2/MF_CMSLINK_ProcessCustomerInquiryDistributed.msgflow"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
The XJC Ant task
<project name="WSDLCompile" default="wsdl2java" basedir=".">
<target name="wsdl2java" description="Run xjc -wsdl.">
<!-- properties -->
<property name="sourceDir" value="temp/src" />
<echo message="sourceDir:"/>
<echo message="${sourceDir}"/>
<mkdir dir="temp/classes"/>
<property name="outputDir" value="temp/classes" />
<echo message="outputDir:"/>
<echo message="${outputDir}"/>
<!-- xjc properties -->
<property name="wsdl.url" value="src/wsdl/cmslink/ProcessCustomerInquiry.wsdl" />
<echo message="wsdl.url:"/>
<echo message="${wsdl.url}"/>
<property name="wsdl.mapping.package.response" value="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry/Response=com.tms.cmslink.rts.service.ProcessCustomerInquiry.Response" />
<echo message="wsdl.mapping.package.response:"/>
<property name="wsdl.mapping.package.request" value="http://service.rts.cmslink.tms.com/ProcessCustomerInquiry/Request=com.tms.cmslink.rts.service.ProcessCustomerInquiry.Request" />
<echo message="wsdl.mapping.package.request:"/>
<!--C:/Program Files/Java/jdk1.7.0_09/bin/xjc -->
<!--xjc execution-->
<exec executable="xjc">
<arg value="-wsdl" />
<arg value="${wsdl.url}" />
<arg value="-d" />
<arg value="${outputDir}" />
<arg value="-p"/>
<arg value="${wsdl.mapping.package.request}"/>
<arg value="-p"/>
<arg value="${wsdl.mapping.package.response}"/>
<arg value="-verbose"/>
</exec>
</target>
</project>
If I remove the extra schema import either response.xsd or request.xsd, and also only include 1 "-p" package namespace argument for the ANT task, than the ANT runs without error, however my wsdl file contains multiple schema imports.
EDIT
I changed the value of "-p" arguement to adhere to package conventions, although my previous approach was based on JXC bug forum.
<project name="WSDLCompile" default="wsdl2java" basedir=".">
<target name="wsdl2java" description="Run xjc -wsdl.">
<!-- properties -->
<property name="sourceDir" value="temp/src" />
<echo message="sourceDir:"/>
<echo message="${sourceDir}"/>
<mkdir dir="temp/classes"/>
<property name="outputDir" value="temp/classes" />
<echo message="outputDir:"/>
<echo message="${outputDir}"/>
<!-- xjc properties -->
<property name="wsdl.url" value="src/wsdl/cmslink/ProcessCustomerInquiry.wsdl" />
<echo message="wsdl.url:"/>
<echo message="${wsdl.url}"/>
<property name="wsdl.mapping.package.response" value="com.tms.cmslink.rts.service.ProcessCustomerInquiry.Response" />
<echo message="wsdl.mapping.package.response:"/>
<property name="wsdl.mapping.package.request" value="com.tms.cmslink.rts.service.ProcessCustomerInquiry.Request" />
<echo message="wsdl.mapping.package.request:"/>
<!--C:/Program Files/Java/jdk1.7.0_09/bin/xjc -->
<!--xjc execution-->
<exec executable="xjc">
<arg value="-wsdl" />
<arg value="${wsdl.url}" />
<arg value="-d" />
<arg value="${outputDir}" />
<arg value="-p"/>
<arg value="${wsdl.mapping.package.request}"/>
<arg value="-p"/>
<arg value="${wsdl.mapping.package.response}"/>
<arg value="-verbose"/>
</exec>
</target>
</project>
I have even tried the above ant task,with
-p <arg value="${wsdl.mapping.package.request }"/>
<arg value="${wsdl.mapping.package.response}"/>
by putting both package names on 1 line separated by space, this is according to JXC doc , explaining you can have "zero or more package namespaces separated by space". I require XJC to be able to handle more than 1 schema import.

The -p option specifies a single Java package that should be used for all generated classes regardless of namespace. If you want each namespace URI to map to its own package then you can't use -p, you instead need to use a binding customization file
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.1">
<bindings schemaLocation="ProcessCustomerInquiryResponse.xsd" node="/xs:schema">
<schemaBindings>
<package name="com.example.inquiry.response"/>
</schemaBindings>
</bindings>
<bindings schemaLocation="ProcessCustomerInquiryRequest.xsd" node="/xs:schema">
<schemaBindings>
<package name="com.example.inquiry.request"/>
</schemaBindings>
</bindings>
</bindings>
and pass it to xjc using the -b option
<arg value="-b"/>
<arg file="bindings.xjb"/>

I think the problem is your Ant script. There are two problems:
The value of the package property must be a java package. Eg: <property name="wsdl.mapping.package" value="com.mycompany.xml.generated"/>
You should only specify the one package not two.
Good luck!
Also, here's a link for a package per schema approach.
-Muel

Related

Read Ant properties file generated by Apache FOP

I am new to Ant. I am trying to read two property files, The first is static and second is created during the build process. Please see below.
There is one static property file which I read in at the top: ./cfg/build.properties.
Then again reading another property file inside a target tag. The flow is described below.
There are two targets which will get executed in sequences.
First I am trying to create a property file using FOP in target GENERATE_PROPERTYFILE.
Then on the second target, READ_PROPERTY_FILE_GENERATE_XML, I am reading the property file created in the first step.
But the issue is, it is not picking a value for ${IssueObjects.ID} from the second property file.
Below is the snapshot of script.
<project name="fop4ant" default="run" basedir=".">
<property file="./cfg/build.properties" prefix="System"/>
<property environment="env"/>
<tstamp>
<format property="param_TouchTimeStamp" pattern="yyyyMMddHHmmssSS"/>
</tstamp>
<property name="param_TouchTimeStamp" value="" />
<property name="prop_File_XSL_FetchProbNSolObjects" value="${System.prop_Dir_stylesheet}/${System.prop_File_Stylesheet_FetchProbSol_CNReport}" />
<property name="prop_File_XML" value="${System.prop_Dir_temp}/Object-${param_TouchTimeStamp}.xml" />
<property name="prop_File_XML_Prob" value="${System.prop_Dir_temp}/Prob-${param_TouchTimeStamp}.xml" />
<property name="prop_File_COIDs" value="${System.prop_Dir_temp}/probCO-${param_TouchTimeStamp}.properties" />
<property name="prop_Dir_FOP" value="${env.FOP_HOME}"/>
<property name="prop_Dir_GS" value="${env.GS_HOME}"/>
<taskdef name="fop"
classname="org.apache.fop.tools.anttasks.Fop">
<classpath>
<fileset dir="${prop_Dir_FOP}/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${prop_Dir_FOP}/build">
<include name="fop.jar"/>
</fileset>
</classpath>
</taskdef>
<!-- #SECTION_BEGIN :: READ_PROPERTY_FILE_GENERATE_XML -->
<target name="generate-problem-item-productview">
<echo message="prop_XML_FILE_PROB :: ${prop_File_XML_Prob}" level="info" />
<!--Reading dynamically created property file-->
<property file="$prop_File_COIDs" prefix="IssueObjects"/>
<exec executable="export.exe">
<arg line="-xml_file=${prop_File_XML_Prob} -transfermode=${IssueObjects.ID}">
</exec>
</target>
<!-- #SECTION_END :: READ_PROPERTY_FILE_GENERATE_XML -->
<!-- #SECTION_BEGIN :: GENERATE_PROPERTYFILE-->
<target name="fetch-prob-sol-items">
<echo message="prop_File_XML :: ${prop_File_XML}" level="info" />
<echo message="prop_File_XSL_FetchProbNSolObjects :: ${prop_File_XSL_FetchProbNSolObjects}" level="info" />
<echo message="prop_File_COIDs :: ${prop_File_COIDs}" level="info" />
<echo message="prop_Dir_FOP :: ${prop_Dir_FOP}/fop.bat" level="info" />
<exec executable="${prop_Dir_FOP}/fop.bat">
<arg value="-xml"/>
<arg value="${prop_File_XML}"/>
<arg value="-xsl"/>
<arg value="${prop_File_XSL_FetchProbNSolObjects}"/>
<arg value="-foout"/>
<arg value="${prop_File_COIDs}"/>
</exec>
</target>
<!-- #SECTION_END :: GENERATE_PROPERTYFILE -->
<target name="run" depends="">
<echo message="start :: run" level="info" />
<antcall target="fetch-prob-sol-items" />
<antcall target="generate-problem-item-productview" />
<echo message="end :: run" level="info" />
</target>
</project>
In the READ_PROPERTY_FILE_GENERATE_XML section, replace the following...
<property file="$prop_File_COIDs" prefix="IssueObjects"/>
...with...
<property file="${prop_File_COIDs}" prefix="IssueObjects"/>
In the above example, curly braces have been added around the prop_File_COIDs reference.

How to regenrate java classes from xjc ant while xsd's are up to date

If xsd are up to date , then xjc are not generating the class.
I want classes always to be generated..
<target name="jaxbSource" description="Generate jaxb objects">
<echo message="Generate jaxb objects for CategoryAPIRequest..." />
<xjc source="2.0" schema="${basedir}/schemas/categoryAPI/CategoryAPIRequest.xsd" package="com.myrio.tm.company.categories.util.request"
destdir="${basedir}/src" binding="${basedir}/schemas/categoryAPI/binding.xml">
<produces dir="${basedir}/src" includes="**/*.java" />
<arg value="-extension" />
</xjc>
<echo message="Generate jaxb objects for CategoryAPIReturn..." />
<xjc source="2.0" schema="${basedir}/schemas/categoryAPI/CategoryAPIReturn.xsd" package="com.myrio.tm.company.categories.util.response"
destdir="${basedir}/src" binding="${basedir}/schemas/categoryAPI/binding.xml">
<produces dir="${basedir}/src" includes="**/*.java" />
<arg value="-extension" />
</xjc>
</target>
-- My Binding xml is :
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:version="2.1">
<jaxb:globalBindings>
<xjc:serializable/>
</jaxb:globalBindings>
</jaxb:bindings>

Having directory reference trouble with Jenkins & Phing

I have set up my first CI environment with Jenkins and Phing and it is mostly running perfectly, though I have a few hiccups I can't resolve. I am constantly having trouble in determining how to reference directories within various parts of my build process, appreciate any thoughts on the below:
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="myProject" default="dev" basedir=".">
<property name="baseDir" value="." />
<property name="resourceDir" value="${baseDir}/resources" />
<property name="srcDir" value="${baseDir}/src" />
<property name="outputDir" value="${baseDir}/build" />
<property name="logDir" value="${baseDir}/build/logs" />
<property name="phpmdRulesets" value="${resourceDir}/phpmd/rulesets" />
<property name="devServer" value="C:\Apache24\htdocs\myProject.com" />
<target name="init">
<mkdir dir="${outputDir}" />
<mkdir dir="${logDir}" />
</target>
<target name="clean">
<delete dir="${devServer}" includeemptydirs="true" verbose="true" failonerror="true" />
<mkdir dir="${devServer}" />
</target>
<target name="test">
<echo msg="Running unit tests" />
<exec executable="phpunit" checkreturn="true">
<arg value="--log-junit=${logDir}/PHPUnit.xml" />
<arg value="--verbose" />
<arg value="--debug" />
<arg value="--coverage-clover=${logDir}/clover.xml" />
<arg path="${baseDir}" />
</exec>
</target>
<target name="build" depends="phpcs, phpmd, phpcpd, phpDox">
<echo msg="Running build" />
<echo msg="Copying files to build directory..." />
<copy todir="${outputDir}">
<fileset dir="${baseDir}">
<include name="**/src/**" />
<include name="**/resources/**" />
</fileset>
</copy>
</target>
<target name="phpcs">
<echo msg="Running phpcs" />
<exec executable="phpcs">
<arg value="--report=checkstyle" />
<arg value="--ignore=${srcDir}/php/Test/*,${srcDir}/php/lib/*" />
<arg value="--report-file=${logDir}/checkstyle.xml" />
<arg path="${srcDir}" />
</exec>
</target>
<target name="phpmd">
<echo msg="Running phpmd" />
<exec executable="phpmd">
<arg path="${srcDir}" />
<arg value="xml" />
<arg value="${phpmdRulesets}/codesize.xml,${phpmdRulesets}/unusedcode.xml,${phpmdRulesets}/naming.xml,${phpmdRulesets}/design.xml" />
<arg value="--reportfile ${logDir}/messdetector.xml" />
<arg value="--exclude ${srcDir}/php/Test/,${srcDir}/php/lib/" />
</exec>
</target>
<target name="phpcpd">
<echo msg="Running phpcpd" />
<exec executable="phpcpd">
<arg value="--log-pmd=${logDir}/phpcpd.xml" />
<arg value="-vvv" />
<arg value="--exclude=${srcDir}/php/Test/,${srcDir}/php/lib/" />
<arg path="${srcDir}" />
</exec>
</target>
<target name="phpDox">
<echo msg="Running phpDox" />
<exec executable="phpdox">
<arg value="${resourceDir}" />
</exec>
</target>
<target name="dev" depends="init, clean, test, build">
<echo msg="Running dev target" />
<copy file="${outputDir}/src/php/index.php" tofile="${devServer}/index.php" />
<copy todir="${devServer}/php">
<fileset dir="${outputDir}/src/php">
<include name="**" />
<exclude name="**/index.php" />
</fileset>
</copy>
<copy todir="${devServer}/api">
<fileset dir="${outputDir}/api/html">
<include name="**" />
</fileset>
</copy>
<copy file="${outputDir}/src/php/lib/phpLogin/index.php" tofile="${devServer}/php/lib/phpLogin/index.php" />
</target>
</project>
Issue 1: phpmd won't output the reportfile yet there are no errors reported in the Jenkins log. Instead it is logging the entire xml to the stdout and reporting it in the Jenkins logs.
myProject > phpmd:
[echo] Running phpmd
Property ${srcDir} => ./src
Property ${phpmdRulesets} => ./resources/phpmd/rulesets
Property ${phpmdRulesets} => ./resources/phpmd/rulesets
Property ${phpmdRulesets} => ./resources/phpmd/rulesets
Property ${phpmdRulesets} => ./resources/phpmd/rulesets
Property ${logDir} => ./build/logs
Property ${srcDir} => ./src
Property ${srcDir} => ./src
[exec] Executing command: phpmd ./src xml ./resources/phpmd/rulesets/codesize.xml,./resources/phpmd/rulesets/unusedcode.xml,./resources/phpmd/rulesets/naming.xml,./resources/phpmd/rulesets/design.xml "--reportfile ./build/logs/messdetector.xml" "--exclude ./src/php/Test/,./src/php/lib/" 2>&1
[exec] <?xml version="1.0" encoding="UTF-8" ?>
...
Issue 2: I am unable to get phpDox to exclude certain directories within my source code. Below is my phpdox.xml.
<?xml version="1.0" encoding="utf-8" ?>
<phpdox xmlns="http://phpdox.de/config">
<project name="myProject.com" source="src/php" workdir="build/api/xml">
<collector backend="parser" publiconly="false">
<include mask="*.php" />
<exclude mask="/lib/**" />
</collector>
<generator output="build/api">
<build engine="html" output="html"/>
</generator>
</project>
</phpdox>
Does anyone know the correct exclude mask I can use please? My file structure is:
myProject.com
/build.xml
/phpdox.xml
/src
/php
/lib
Both issues resolved.
Issue 1: Changed the phpmd task to only use arg values and not arg path. Fixed below:
<target name="phpmd">
<echo msg="Running phpmd" />
<exec executable="phpmd">
<arg value="${dir.src}" />
<arg value="xml" />
<arg value="${dir.phpmdRulesets}/codesize.xml,${dir.phpmdRulesets}/unusedcode.xml,${dir.phpmdRulesets}/naming.xml,${dir.phpmdRulesets}/design.xml" />
<arg value="--reportfile" />
<arg value="${dir.logs}/messdetector.xml" />
<arg value="--exclude"/>
<arg value="test,lib" />
</exec>
</target>
Issue 2: Finally got the exclude masks to work. Fixed xml below:
<?xml version="1.0" encoding="utf-8" ?>
<phpdox xmlns="http://phpdox.de/config">
<project name="myProject.com" source="src/app" workdir="build/api/xml">
<collector backend="parser" publiconly="false">
<include mask="*.php" />
<exclude mask="**/*lib*" />
<exclude mask="**/*test*" />
</collector>
<generator output="build/api">
<build engine="html" output="html"/>
</generator>
</project>
</phpdox>

MXMLC ANT for building AIR application

I'm used a script ANT, with MXMLC task to build my AIR application. The generation is oK (.swf is generated). But the xxx-app.xml is not generated too ?
<mxmlc
file="${src.dir}/${trinity.project}.mxml"
output="${release.dir}/${trinity-client}.swf"
locale="fr_FR"
static-rsls="true"
accessible="true"
configname="air"
debug="false"
failonerror="true"
fork="true"
optimize="true"
maxmemory="512m">
<load-config filename="${FLEX_HOME}/frameworks/air-config.xml" />
<source-path path-element="${FLEX_HOME}/frameworks"/>
<source-path path-element="${src.dir}"/>
<use-network>true</use-network>
<external-library-path file="${FLEX_HOME}/frameworks/libs/air/airglobal.swc" append="true"/>
<library-path dir="${ivy.cache.dir}" append="true">
<include name="${puremvc.lib}"/>
<include name="${kccalendar.lib}"/>
<include name="${as3commons.lib}"/>
</library-path>
</mxmlc>
Have you got a solution ?
Thank you very much,
Anthony
You need to call adt in the sdk folder, to make a .air package.
eg:
<target name="execute.air">
<condition property="adt.name" value="adt">
<os family="unix" />
</condition>
<condition property="adt.name" value="adt.bat">
<os family="windows" />
</condition>
<exec executable="${FLEX_HOME}/bin/${adt.name}" failonerror="true">
<arg line="-package" />
<arg line="-tsa none" />
<arg line="-storetype pkcs12" />
<arg line="-keystore ${basedir}/keys/${APP_NAME}.p12" />
<arg line="-storepass password" />
<arg line="${DEPLOY_DIR}/${APP_NAME}.air" />
<arg line="${SRC_DIR}/${APP_NAME}-app.xml" />
<arg line="-C ${DEPLOY_DIR} ${APP_NAME}.swf" />
</exec>
</target>

ANT script to compile all (css) LESS files in a dir and subdirs with RHINO

I want do compile all *.less scripts in a specific folder and it subdirs with less-rhino-1.1.3.js.
There is an example on github for doing this for a specific file, which works perfect. But I want to do the same for a complete folder. I tried a lot, here is my last try.
It doesn't work, propertyregex seems not to be standard ANT, I don't want to use such things. I am not even sure if this code would work.
<project name="test" default="main" basedir="../../">
<property name="css.dir" location="public/css"/>
<property name="tool.less" location="bin/less/less-rhino-1.1.3.js"/>
<property name="tool.rhino" location="bin/tools/rhino/js.jar"/>
<macrodef name="lessjs">
<attribute name="input" />
<attribute name="output" />
<sequential>
<java jar="${tool.rhino}" fork="true" output="#{output}">
<arg path="${tool.less}"/>
<arg path="#{input}"/>
</java>
<echo>Lessjs: generated #{output}</echo>
</sequential>
</macrodef>
<target name="main">
<echo>compiling less css</echo>
<fileset dir="${css.dir}" id="myfile">
<filename name="**/*.less" />
</fileset>
<property name="lessfilename" refid="myfile"/>
<propertyregex property="cssfilename"
input="${lessfile}"
regexp="^(.*)\.less$"
replace="^\1\.css$"
casesensitive="true" />
<lessjs input="lessfile" output="cssfilename"/>
</target>
</project>
You could use the <fileset> to include all the less files need to be compiled. Later, you could use<mapper> to mark the corresponding detination css file.
<project name="test" default="main" basedir="../../">
<property name="css.dir" location="public/css"/>
<property name="tool.less" location="bin/less/less-rhino-1.1.3.js"/>
<property name="tool.rhino" location="bin/tools/rhino/js.jar"/>
<target name="less" description="Convert LESS to CSS then concatenate and Minify any stylesheets">
<echo message="Converting LESS to CSS..."/>
<!-- Clear the former compiled css files -->
<delete includeemptydirs="true">
<fileset dir="${css.dir}" includes="*.css, **/*.css" defaultexcludes="false"/>
</delete>
<apply dir="${css.dir}" executable="java" parallel="false" failonerror="true">
<!-- Give the input bundle of less files-->
<fileset dir="${css.dir}">
<include name="*.less"/>
</fileset>
<arg value="-jar" />
<arg path="${tool.rhino}" />
<arg path="${tool.less}" />
<srcfile/>
<!-- Output the compiled css file with corresponding name -->
<mapper type="glob" from="*.less" to="${css.dir}/*.css"/>
<targetfile/>
</apply>
</target>
</project>
I was able to piece together a working solution with the help of a couple of SO answers:
ANT script to compile all (css) LESS files in a dir and subdirs with RHINO
How to correctly execute lessc-rhino-1.6.3.js from command line
I had to download LESS 1.7.5 from GitHub and modify the Ant target to look like this. The -f argument and LESS JavaScript was key:
<property name="css.dir" value="WebContent/css"/>
<property name="less.dir" value="less"/>
<property name="tool.rhino.jar" value="test-lib/rhino-1.7R4.jar"/>
<property name="tool.rhino.lessc" value="test-lib/lessc-rhino-1.7.5.js"/>
<property name="tool.rhino.less" value="test-lib/less-rhino-1.7.5.js"/>
<target name="compile-less" description="compile css using LESS">
<apply dir="${css.dir}" executable="java" parallel="false" failonerror="true">
<fileset dir="${less.dir}">
<include name="styles.less"/>
</fileset>
<arg value="-jar"/>
<arg path="${tool.rhino.jar}"/>
<arg value="-f"/>
<arg path="${tool.rhino.less}"/>
<arg path="${tool.rhino.lessc}"/>
<srcfile/>
<mapper type="glob" from="*.less" to="${css.dir}/*.css"/>
<targetfile/>
</apply>
</target>
If anyone else is coming to this question recently, as I did, they may find that the less-rhino-1.1.3.js file given in the other answers does not work with the latest version of Rhino (which for me, as of now, is 1.7R4 from MDN). But the 1.4.0 version does, which can be obtained from Github here. So the relevant snippet from my build.xml, using these later versions, is shown. Note that I'm only compiling a single .less file to a single .css file, so no iteration or mappers are used (but obviously you can get those from the other answers). Other tweaks I made were to provide the output file as the final arg to less instead of capturing output from the Ant forked process, and to remove the dependency on ant-contrib stuff (not needed for the simple one-file case).
<property name="tool.rhino" value="build/lesscss/rhino1_7R4/js.jar" />
<property name="tool.less" value="build/lesscss/less-rhino-1.4.0.js" />
<property name="single-input-lesscss-file" value="/path/to/my/style.less" />
<property name="single-output-css-file" value="/output/my/style.css" />
<target name="compileLessCss" description="Compile the single less file to css">
<sequential>
<java jar="${tool.rhino}" fork="true">
<arg path="${tool.less}" />
<arg path="${single-input-lesscss-file}" />
<arg path="${single-output-css-file}" />
</java>
</sequential>
</target>
If maven is an option for you, you could try wro4j-maven-plugin or wro4j-runner (which is a command line utility).
Using one of these, all you have do is to create an resource model descriptor (wro.xml):
<groups xmlns="http://www.isdc.ro/wro">
<group name="g1">
<css>/path/to/*.less</css>
</group>
</groups>
The rest will be handled by the wro4j library. No need to carry about how rhino works or other details.
Disclaimer: I'm working on wro4j project
I had the same issue. I developed a solution using ant-contrib. It expects all of your .less files to be in one flat directory and to be moved to another flat directory. It will change the file extension to .css in the process.
<property name="tool.rhino" value="/rhino/js.jar" />
<property name="tool.less" value="src/js/less-rhino-1.1.3.js" />
<property name="tool.ant-contrib" value="/ant-contrib/ant-contrib-1.0b3-1.0b3.jar" />
<property name="less-files-dir" value="src/css/" />
<property name="css-files-dir" value="build/css/" />
<target name="compilecss" depends="setup-ant-contrib-taskdef, get-less-files-in-dir" description="DO THIS THING">
<for list="${less-files-to-convert}" param="file-name" trim="true" delimiter=",">
<sequential>
<propertyregex property="file-name-without-extension"
input="#{file-name}"
regexp="(.*)\..*"
select="\1"
override="yes" />
<java jar="${tool.rhino}" fork="true" output="${css-files-dir}${file-name-without-extension}.css">
<arg path="${tool.less}" />
<arg path="${less-files-dir}#{file-name}" />
</java>
<echo>Lessjs: generated ${css-files-dir}${file-name-without-extension}.css</echo>
</sequential>
</for>
</target>
<target name="check-for-ant-contrib">
<condition property="ant-contrib-available">
<and>
<available file="${tool.ant-contrib}"/>
</and>
</condition>
<fail unless="ant-contrib-available" message="Ant-Contrib is not available."/>
</target>
<target name="setup-ant-contrib-taskdef" depends="check-for-ant-contrib">
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<path location="${tool.ant-contrib}" />
</classpath>
</taskdef>
</target>
<target name="get-less-files-in-dir">
<var name="files-list" value="" />
<for param="file">
<path>
<fileset dir="${less-files-dir}" includes="**/*.less" />
</path>
<sequential>
<propertyregex property="file-name-and-relative-path"
input="#{file}"
regexp=".*\\(.*)"
select="\1"
override="yes" />
<echo>file name: ${file-name-and-relative-path}</echo>
<if>
<equals arg1="${files-list}" arg2="" />
<then>
<var name="files-list" value="${file-name-and-relative-path}" />
</then>
<else>
<var name="files-list" value="${files-list},${file-name-and-relative-path}" />
</else>
</if>
</sequential>
</for>
<property name="less-files-to-convert" value="${files-list}" />
<echo>files to convert: ${less-files-to-convert}</echo>
</target>
I was unable to get this to run using a JDK 1.6 since the javascript stuff has been incorporated to the JDK. The JDK does have a jrunscript executable in the distribution but when I try to run the less-rhino.js file it fails to recognize any readFile() function. Has anyone looked into that. Otherwise I may be giving the lesscss-engine a shot and enhancing it to understand filesets.

Resources