Netbeans ant build error 'unsupported element customize' - java

I updated to Netbeans 8.0.1 from 7.0.1 and my java program compiles fine if 'Web Start' is disabled. As soon as 'Web Start' is enabled I get the following error:
C:\NetBeansProjects\SearchCriteriaEditor\nbproject\jnlp-impl.xml:480:
unsupported element customize
in this section of the jnlp-impl.xml file:
<target name="-do-jar-jnlp-application" depends="-init-filename,-test-jnlp-type,-init-macrodef-copylibs" if="is.application+mkdist.available">
<j2seproject3:copylibs manifest="${tmp.manifest.file}">
<customize>
<attribute name="Main-Class" value="${main.class}"/>
</customize>
</j2seproject3:copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${jnlp.dest.dir}/${jnlp.file}" name="jnlp.file.resolved"/>
<echo>javaws "${jnlp.file.resolved}"</echo>
</target>
The fix, as I understand it is to: 'add following to customized junit macro definition:'
<attribute default="" name="testmethods"/>
<element name="customize" optional="true"/>
<customize/>
Trouble is I have no idea where that is, nor have I modified my ant file in any way...can anyone give me a bit more information? I assume the fix goes somewhere in the jnlp-impl.xml file; I just have no idea where to put it.
Edit update: added all sections with references to 'copylibs' in the jnlp-impl.xml file-
<target name="-test-jnlp-type" depends="-test-jnlp-enabled" if="is.jnlp.enabled">
<condition property="is.applet">
<equals arg1="${jnlp.descriptor}" arg2="applet" trim="true"/>
</condition>
<condition property="is.application">
<equals arg1="${jnlp.descriptor}" arg2="application" trim="true"/>
</condition>
<condition property="is.component">
<equals arg1="${jnlp.descriptor}" arg2="component" trim="true"/>
</condition>
<condition property="is.applet+mkdist.available">
<and>
<isset property="libs.CopyLibs.classpath"/>
<istrue value="${is.applet}"/>
</and>
</condition>
<condition property="is.application+mkdist.available">
<and>
<isset property="libs.CopyLibs.classpath"/>
<istrue value="${is.application}"/>
</and>
</condition>
<condition property="is.component+mkdist.available">
<and>
<isset property="libs.CopyLibs.classpath"/>
<istrue value="${is.component}"/>
</and>
</condition>
</target>
......
<target name="-do-jar-jnlp-application" depends="-init-filename,-test-jnlp-type,-init-macrodef-copylibs" if="is.application+mkdist.available">
<j2seproject3:copylibs manifest="${tmp.manifest.file}">
<customize>
<attribute name="Main-Class" value="${main.class}"/>
</customize>
</j2seproject3:copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${jnlp.dest.dir}/${jnlp.file}" name="jnlp.file.resolved"/>
<echo>javaws "${jnlp.file.resolved}"</echo>
</target>
<target name="-do-jar-jnlp-component" depends="-test-jnlp-type,-init-macrodef-copylibs" if="is.component+mkdist.available">
<j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
</target>
Thanks in advance.

<j2seproject3:copylibs invokes the macrodef copylibs with the namespace prefix j2seproject3. There should be a place in the buildfile where the copylibs macro is defined, in a way similar (but not necessarily exact) to:
<macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
The above line should logically exist inside the -init-macrodef-copylibs target, and this is where the customize element should be defined as well. Below is the snippet based on a sample NetBeans project I have. The content will probably not match exactly the one you have, so take my answer with a grain of salt:
<macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
... <!-- some attributes may be defined here first -->
<element name="customize" optional="true"/> <!-- customize should be defined here -->
<sequential>
...
<!-- somewhere in the macrodef -->
<copylibs compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Class-Path" value="${jar.classpath}"/>
<customize/> <!-- this is where customize is used -->
</manifest>
</copylibs>
...
</sequential>
</macrodef>

Related

Conditional task execution in ANT Scripts

My requirement is pretty simple, I have an ANT task which is handling exceptions internally and not throwing any exception, instead it is throwing custom messages [these are not exceptions] to the console. A sample is shown below with the test "The workspace with the specified name does not exist".
My requirement here is, if there is any such message apart from "Build Successful", I should make sure my ANT script is failed so that it won't go further. But I am unable to do so as I don't know how do I read that custom message which was written to console.
I tried exploring on 'Record' task but I was unsuccessful as this log was written only to console and not to the file (don't know why). But even if it was written to a file I should ideally read each line of file to find out a particular text present or not.
Is there a simple way to try and read things from console which were executed before?
<target name="build">
<record name="test.txt" action="start" append="true" loglevel="verbose" />
<echo>Welcome to Apache Ant! Building the project in Cordys Middleware</echo>
<property environment="env"/>
<property name="bop.install.dir" value="${env.CORDYS_HOME}"/>
<exec executable="${bop.install.dir}/components/cws/scripts/linux/CWSPackage.sh" failonerror="true" resultproperty="output">
<env key="CLASSPATH" value="/opt/Cordys/Oracle_Jar/ojdbc6.jar"/>
<arg value="${ORG_NAME}"/>
<arg value="${WORKSPACE_NAME}"/>
<arg value="${PROJECT_NAME}"/>
</exec>
<echo>Finishing the build</echo>
<record name="test.txt" action="stop"/>
<echo>${output}</echo>
<fail>Something wrong here.</fail> <!-- I want to throw this error conditionally -->
</target>
What you're looking for is the exec task's outputproperty attribute.
You can do something like this:
<exec executable="${my.executable}" outputproperty="exec.output">
<arg value="${my.arg}" />
</exec>
<fail message="Invalid output from exec task">
<condition>
<contains string="${exec.output}" substring="The workspace with the specified string does not exist." />
</condition>
</fail>
Multiple conditions (any level of complexity in the boolean is allowed):
<fail message="Invalid output from exec task">
<condition>
<and>
<not>
<contains string="${exec.output}" substring="SUCCESS" />
</not>
<or>
<contains string="${exec.output}" substring="ERROR" />
<contains string="${exec.output}" substring="FAILED" />
<or>
</and>
</condition>
</fail>
Regex:
<fail message="Invalid output from exec task">
<condition>
<matches string="${exec.output}" pattern="The .* does not exist." />
</condition>
</fail>
<!-- * This is an ANT script to build the project in development environment.
Steps involved in this are
* Building the project
* Publishing the project
* Creating the package for the project
-->
<!--
Sample command to execute this
ant build -DORG_NAME=businessservices3 -DWORKSPACE_NAME=ConfigurationManagement -DPROJECT_NAME='ConfigurationManagement'
-->
<project name="Building Project" default="build">
<property file="${PROJECT}" />
<target name="build">
<echo>Welcome to Apache Ant! Building the project in Cordys Middleware</echo>
<property environment="env"/>
<property name="bop.install.dir" value="${env.CORDYS_HOME}"/>
<exec executable="${bop.install.dir}/components/cws/scripts/linux/CWSPackage.sh" outputproperty="exec.output">
<env key="CLASSPATH" value="/opt/Cordys/Oracle_Jar/ojdbc6.jar"/>
<arg value="${ORG_NAME}"/>
<arg value="${WORKSPACE_NAME}"/>
<arg value="${PROJECT_NAME}"/>
</exec>
<fail message="Build not successful for the project ${PROJECT_NAME}">
<condition>
<not>
<contains string="${exec.output}" substring="Operation completed successful" />
</not>
</condition>
</fail>
</target>
</project>
This worked for me after so much of trail and error methods.
Thanks Austin. Even though this is the ANT which is working, I would accept your answer only as this is a modified version of what you told :)

Include a File If a Condition Is Met Inside Apache Ant fileset

Is there a way to include or exclude certain files based on a condition in Apache Ant (1.8.3)? For instance, I have a macrodef that takes an attribute. I would like to include certain files if the attribute's value matches xyz:
<macrodef name="pkgmacro">
<attribute name="myattr" />
<sequential>
<zip destfile="${dist}/#{myattr}.war">
<fileset dir="${dist}/webapp" >
<include name="**/#{myattr}/**" />
<exclude name="WEB-INF/config/**" />
<!-- if #{myattr} = "xyz", then
<include name="PATH/TO/file.xml" />
-->
</fileset>
<zipfileset dir="${ear}/#{myattr}/WEB-INF/" includes="*.xml" prefix="WEB-INF/" />
</zip>
</sequential>
</macrodef>
For instance, if myattr value is xyz, I would like to include the commented file in portion above.
Fileset can use nested include/exlucde patternsets with if/unless
Attribute. The pattern is included/excluded when a named property is set or not, so no ant addons needed.Some snippet :
<project>
<!-- property that triggers your include/exclude
maybe set via condition in some other target .. -->
<property name="foo" value="bar"/>
<macrodef name="pkgmacro">
<attribute name="myattr" />
<sequential>
<fileset dir="C:/whatever" id="foobar">
<!-- alternatively
<include name="*.bat" unless="#{myattr}"/>
-->
<include name="*.bat" if="#{myattr}"/>
</fileset>
<!-- print fileset contents -->
<echo>${toString:foobar}</echo>
</sequential>
</macrodef>
<pkgmacro myattr="foo"/>
</project>
--EDIT after comment --
The if/unless attribute after include name/exclude name checks whether the given value is a property which is set (when using if="..") or not set (when using unless="..") in the ant project scope - it doesn't check for a specific value.
<include name="*.xml" unless="foo"/>
means include is only active if no property named foo is set in your project
<include name="*.xml" if="foo"/>
means include is only active if property named foo is set in your project
Works fine for me , used Ant 1.7.1, had no Ant 1.8.x around right now :
<project>
<echo>$${ant.version} => ${ant.version}</echo>
<macrodef name="pkgmacro">
<attribute name="myattr"/>
<sequential>
<condition property="pass">
<equals arg1="#{myattr}" arg2="xyz" />
</condition>
<fileset dir="C:/whatever" id="foobar">
<include name="*.bat" if="pass" />
</fileset>
<echo>${toString:foobar}</echo>
</sequential>
</macrodef>
<pkgmacro myattr="xyz"/>
</project>
output :
[echo] ${ant.version} => Apache Ant version 1.7.1 compiled on June 27 2008
[echo] switchant.bat;foobar.bat;foo.bat
-- EDIT after comment --
Using serveral include patterns works fine :
...
<fileset dir="C:/whatever" id="foobar">
<include name="*.xml" if="pass" />
<include name="*.bat" if="pass"/>
<include name="**/*.txt" if="pass"/>
</fileset>
...
maybe you're using the wrong patterns ?
-- EDIT after comment --
Here is the reference to <local> task which is needed to work with the properties in the current scope, in this case, <sequential>:
<macrodef name="pkgmacro">
<attribute name="myattr"/>
<sequential>
<!-- make property pass mutable -->
<local name="pass"/>
<condition property="pass">
<equals arg1="#{myattr}" arg2="xyz" />
</condition>
<fileset dir="C:/whatever" id="foobar">
<include name="*.xml" if="pass" />
<include name="*.bat" if="pass" />
<include name="**/*.txt" if="pass" />
</fileset>
<!-- print value of property pass and fileset contents -->
<echo>$${pass} = ${pass}${line.separator}${toString:foobar}</echo>
</sequential>
</macrodef>
if you can use ant-contrib, then try this:
<contrib:if>
<equals arg1="${myattr}" arg2="xyz" />
<then>
<include name="PATH/TO/file.xml" />
</then>
</contrib:if>
if you can't use ant-contrib, try this:
http://jaysonlorenzen.wordpress.com/2010/03/10/apache-ant-if-else-condition-without-ant-contrib/

Ant using antlib with namespace

I am using the following demonstration script:
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" basedir="." xmlns:deploy="antlib:net.sf.antcontrib">
<target name="default">
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<deploy:if>
<isset property="defaultprop"/>
<then>
<echo message="it's set!"/>
</then>
</deploy:if>
</target>
</project>
When I run this build script (with target default), the error is
build.xml:9: Problem: failed to create task or type antlib:net.sf.antcontrib:if
The pathelement lib/ant-contrib-1.0b3.jar exists, and ant is picking it up. I'm thinking the problem is how I'm using the xmlns. I'm taking this from another example that I have that also doesn't work for me (it works on a particular server, though!), and trying to figure out what the magic sauce is.
Your taskdef where you're adding ant-contrib needs to declare a URI the same as the namespace you're defining and prefixing in the project. Similar to how the taskdef over here works.
<project name="test" basedir="." xmlns:deploy="antlib:net.sf.antcontrib">
<target name="default">
<taskdef uri="antlib:net.sf.antcontrib" resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<deploy:if>
<isset property="defaultprop"/>
<then>
<echo message="it's set!"/>
</then>
</deploy:if>
</target>
</project>
Well, the error has if on the end, and it's talking about line 9. I think it's a problem with the syntax of this tag:
<deploy:if>
I can't find any documentation on a "deploy:if" tag, or even a "deploy" tag. I think there is no 'deploy' task in Ant - you need to make a 'deploy' target.
How about trying this:
<if>
<isset property="defaultprop"/>
<then>
<antcall target="deploy" />
</then>
</if>
As I read it, this will check the isset, then call the "deploy" target if it's set.
Of course, you need to make the 'deploy' target now :)

How do I sign a dozen JAR files with jarsigner?

I want to sign two dozen jar files using jarsigner, giving the password only once.
Giving multiple files to jarsigner is not possible, according to the man page and using a for-loop on the command line still forces me to input the password for every file.
I would prefer a solution for the command line, but would be okay with ant/maven solution.
System is Linux.
How do I sign a dozen jar-files, giving the password only once?
Here is a snippet from the Ant build file for PSCode - it signs a slew of Jars. The trick is in the foreach element.
<target name="createjars"
depends="compile"
description="Jars the compiled classes">
<mkdir dir="${build}/jar/" />
<foreach target="jar.package" param="package" inheritall="true">
<path>
<dirset dir="${src}/java/org/pscode" includes="**/*" />
</path>
</foreach>
</target>
..and..
<target name='jar.package'>
<script language='javascript'>
<![CDATA[
prop = pscode.getProperty('package');
index1 = prop.lastIndexOf('pscode') + 7;
index2 = prop.length();
prop1 = prop;
path = prop1.substring( index1, index2 );
path2 = path.replaceAll('\\\\','/');
pscode.setProperty('path', path2 );
name = path2.replaceAll('/','.');
pscode.setProperty('jar.name', name + '.jar' );
]]>
</script>
<xmlproperty file="${src}/java/org/pscode/${path}/manifest.xml" />
<!-- echo message='jar.name: ${jar.name} *** ${application.title}' / -->
<if>
<not>
<uptodate targetfile='${build}/dist/lib/${jar.name}' >
<srcfiles dir= '${build}/share/org/pscode/${path}' includes='*.class'/>
</uptodate>
</not>
<then>
<jar
destfile='${build}/dist/lib/${jar.name}'
index='true'
update='true'>
<manifest>
<attribute name="Implementation-Title" value="${application.title}" />
<attribute name="Implementation-Vendor" value="${vendor}" />
<attribute name="Implementation-Vendor-Id" value="org.pscode" />
<attribute name='Implementation-Version' value='${now}' />
</manifest>
<fileset dir='${build}/share'>
<include name='org/pscode/${path}/*.class' />
</fileset>
<fileset dir='${src}/java'>
<include name='org/pscode/${path}/*.png' />
<include name='org/pscode/${path}/*.jpg' />
<include name='org/pscode/${path}/*.gif' />
<include name='org/pscode/${path}/*.xml' />
<include name='org/pscode/${path}/*.html' />
<include name='org/pscode/${path}/*.ser' />
</fileset>
</jar>
</then>
</if>
<!-- If the Jar is updated, any previous signatures will be invalid, it
needs to be signed again. We cannot use the issigned condition since
that merely checks if a Jar is signed, not if the digital signatures are
valid. -->
<exec
executable='${jar.signer}'
resultproperty='jar.signer.result.property'
outputproperty='jar.signer.output.property'>
<arg value='-verify' />
<arg value='${build}/dist/lib/${jar.name}' />
</exec>
<if>
<or>
<not>
<equals arg1='${jar.signer.result.property}' arg2='0' />
</not>
<or>
<contains
string='${jar.signer.output.property}'
substring='unsigned'
casesensitive='false' />
<or>
<contains
string='${jar.signer.output.property}'
substring='SecurityException'
casesensitive='false' />
</or>
</or>
</or>
<then>
<signjar
jar='${build}/dist/lib/${jar.name}'
alias='pscode'
storepass='${sign.password}'
force='true'
verbose='${verbose}'
keystore='${user.home}/${sign.pathfilename}' />
</then>
</if>
</target>
Just for the records: jarsigner is able to read the keystore and key passwords from a file or from an environment variable, using the -keypass / -storepass command line option together with the :file or the :env modifier.
So, it's possible to put each of the passwords in a file (in my example: ~/.storepass and ~/.keypass) and use a for loop like this to sign all jars in the current directory using the key key_alias:
for i in ./*.jar; do jarsigner -storepass:file ~/.storepass -keypass:file ~/.keypass "$i" key_alias;done
To make jarsigner read the passwords from an env variable, you'll have to create those variables first:
export storepass="mystorepassword"
export keypass="mykeypassword"
Now, the loop would look like:
for i in ./*.jar; do jarsigner -storepass:env storepass -keypass:env keypass jarfile.jar key_alias;done

ant filtering - fail if property not set

I've got a ant build.xml that uses the <copy> task to copy a variety of xml files. It uses filtering to merge in properties from a build.properties file. Each environment (dev, stage, prod) has a different build.properties that stores configuration for that environment.
Sometimes we add new properties to the Spring XML or other config files that requires updating the build.properties file.
I want ant to fail fast if there are properties missing from build.properties. That is, if any raw #...# tokens make it into the generated files, I want the build to die so that the user knows they need to add one or more properties to their local build.properties.
Is this possible with the built in tasks? I couldn't find anything in the docs. I'm about to write a custom ant task, but maybe I can spare myself the effort.
Thanks
If you are looking for a specific property, you can just use the fail task with the unless attribute, e.g.:
<fail unless="my.property">Computer says no. You forgot to set 'my.property'!</fail>
Refer to the documentation for Ant's fail task for more detail.
You can do it in ant 1.7, using a combination of the LoadFile task and the match condition.
<loadfile property="all-build-properties" srcFile="build.properties"/>
<condition property="missing-properties">
<matches pattern="#[^#]*#" string="${all-build-properties}"/>
</condition>
<fail message="Some properties not set!" if="missing-properties"/>
I was going to suggest that you attempt to use <property file="${filter.file}" prefix="filter"> to actually load the properties into Ant, and then fail if any of them are not set, but I think I was interpreting your problem wrong (that you wanted to fail if a specified property was not set in the properties file).
I think your best bet might be to use <exec> to (depending on your dev platform) do a grep for the "#" character, and then set a property to the number of occurences found. Not sure of exact syntax but...
<exec command="grep \"#\" ${build.dir} | wc -l" outputproperty="token.count"/>
<condition property="token.found">
<not>
<equals arg1="${token.count}" arg2="0"/>
</not>
</condition>
<fail if="token.found" message="Found token # in files"/>
if exec command is deprecated in your version of ant you can use redirectors, something like:
<exec executable="grep">
<arg line="# ${build.dir}"/>
<redirector outputproperty="grep.out"/>
</exec>
<exec executable="wc" inputstring="${grep.out}">
<arg line="-l"/>
<redirector outputproperty="token.found"/>
</exec>
to create the token.found property
<condition property="token.found">
<not>
<equals arg1="${token.count}" arg2="0"/>
</not>
</condition>
<fail if="token.found" message="Found token # in files"/>
for the conditonal
Since Ant 1.6.2 condition can also be nested inside fail.
The following macro makes it easy to conditionally check multiple properties.
<macrodef name="required-property">
<attribute name="name"/>
<attribute name="prop" default="#{name}"/>
<attribute name="if" default="___"/>
<attribute name="unless" default="___"/>
<sequential>
<fail message="You must set property '#{name}'">
<condition>
<and>
<not><isset property="#{prop}"/></not>
<or>
<equals arg1="#{if}" arg2="___"/>
<isset property="#{if}"/>
</or>
<or>
<equals arg1="#{unless}" arg2="___"/>
<not><isset property="#{unless}"/></not>
</or>
</and>
</condition>
</fail>
</sequential>
</macrodef>
<target name="required-property.test">
<property name="prop" value=""/>
<property name="cond" value="set"/>
<required-property name="prop"/>
<required-property name="prop" if="cond"/>
<required-property name="prop" unless="cond"/>
<required-property name="prop" if="cond2"/>
<required-property name="prop" unless="cond2"/>
<required-property name="prop" if="cond" unless="cond"/>
<required-property name="prop" if="cond" unless="cond2"/>
<required-property name="prop" if="cond2" unless="cond"/>
<required-property name="prop" if="cond2" unless="cond2"/>
<required-property name="prop2" unless="cond"/>
<required-property name="prop2" if="cond2"/>
<required-property name="prop2" if="cond2" unless="cond"/>
<required-property name="prop2" if="cond" unless="cond"/>
<required-property name="prop2" if="cond2" unless="cond2"/>
<required-property name="success"/>
</target>

Categories

Resources