Get maven runtime dependencies in ant - ant

I want to get the set of runtime dependencies from maven in ant. I'm using the maven ant tasks.
I know that you can limit the dependencies by scope (see docs):
<artifact:dependencies filesetId="dependency.fileset" useScope="runtime">
<artifact:pom file="pom.xml" id="myProject" />
</artifact:dependencies>
and that the scope options (from the docs) are:
•compile - Includes scopes compile, system and provided
•runtime - Includes scopes compile and runtime
•test - Includes scopes system, provided, compile, runtime and test
However, I want to get only the runtime dependencies (i.e. exclude compile dependencies). My best idea so far is to get the runtime dependencies and the compile dependencies, and iterate through the runtime dependencies to find those that are not in the compile dependencies, but I haven't yet worked out how to do this.
Any ideas?

You need something along the lines of:
...
<artifact:pom id="maven.project" file="pom.xml"/>
<artifact:dependencies useScope="runtime"
filesetId="dependencies.runtime"
pomRefId="maven.project"
settingsFile="${settings.xml}"/>
...
Then you can use the dependencies.runtime fileset as usual.
I hope this makes more sense.

So this what I tried to get the difference of the runtime and compile file sets (although this makes the assumption that there's nothing in the compile fileset that's not also in the runtime fileset)
<artifact:dependencies filesetId="runtime" scopes="runtime">
<artifact:pom file="pom.xml" id="myProject" />
</artifact:dependencies>
<artifact:dependencies filesetId="compile" scopes="compile">
<artifact:pom file="pom.xml" id="myProject" />
</artifact:dependencies>
<difference id="difference" >
<resources refid="runtime" />
<resources refid="compile" />
</difference>
However, this wasn't producing the results that I expected, so I did the following, and found that the runtime fileset did not contain the compile dependencies.
<echo message="${toString:runtime}" />
<echo message="${toString:compile}" />
So I can just use the runtime scope...

Related

Selecting correct IVY dependency

I have a project that makes use of some third-party libraries. Some of these drag in transitive dependencies that have actually several artifacts in the repository:
module-1.2.jar
module-1.2-sources.jar
module-1.2-tests.jar
My investigations tought me that these seem to be Maven build artifacts that where propagated with a classifier. Now it seems that IVY is well able to handle the sources file but when I declare a dependency like this, it appears that the wrong jar is selected:
<dependency org="acme" module="module" rev="1.2"/>
When I do a resolve in ANT like this
<ivy:resolve conf="${ivy.non.test.confs}" validate="false" refresh="true" />
<ivy:retrieve conf="${ivy.non.test.confs}" pattern="${build.lib}/[conf]/[artifact].[ext]" sync="true" />
it happens that the module-1.2-tests.jar is selected as resolve target and retrieved under the name of the actual jar name (module-1.2.jar in this example).
What am I doing wrong here?

ojdeploy - ant task compile application

I am trying to use ojdeploy to compile and build an ADF application through an AntTask.
The ojdeploy task works fine when I specify not to compile the project by adding the line
The ojdeploy task is unable to find several jars required to build the application which I have specified.
I can't find any documentation which describe the use of the ojdeploy to compile applications which makes me think that it does not work.
The ant task I have is below. My thoughts are that the ojdeploy task does not have the jars required to build the project on its classpath. I can't see a way to add these jars to the classpath however.
ojdeploy task:
<target name="deploy" description="Deploy JDeveloper profiles">
<property name="status" value="${env.WORKSPACE}/deploy/ojdeploy-statuslog.xml"/>
<taskdef name="ojdeploy"
classname="oracle.jdeveloper.deploy.ant.OJDeployAntTask"
uri="oraclelib:OJDeployAntTask"
classpathref="classpath"/>
<ora:ojdeploy xmlns:ora="oraclelib:OJDeployAntTask"
executable="${env.oracle.middleware}/jdeveloper/jdev/bin/ojdeploy.exe"
failonerror="true"
ora:buildscript="${env.WORKSPACE}/deploy/ojdeploy-build.xml"
ora:statuslog="C:/Oracle/Middleware/ojdeploy-statuslog.xml">
<ora:deploy>
<ora:parameter name="workspace"
value="${env.WORKSPACE}/JWS.jws"/>
<ora:parameter name="profile"
value="*"/>
<!--<ora:parameter name="nocompile" value="true"/>-->
<ora:parameter name="outputfile"
value="${env.WORKSPACE}/deploy/${deployment.profile.name}"/>
</ora:deploy>
</ora:ojdeploy>
</target>
Resolved.
ojdeploy uses the jws and jpr files to find the libraries required. The jpr file was missing several JDeveloper/ADF libraries which JDeveloper is able to resolve.
However for ojdeploy to work ALL the libraries and dependencies are required to be in the jws/jpr file accordingly using the libraries/classpath and dependencies options.

Ant attributes duplication for javac

I have an Ant build with a lot of javac tasks.
I want all of them to be executed with the following attributes:
debug = "true" debuglevel = "lines,vars,source"
(by default debugging information is turned off which makes it harder to investigate the console).
Is it possible to provide such attributes in some centralized place which will have influence for all javac tasks in current Ant build? (I don't want duplicating them over all javac tasks...)
You need ant's presetdef
From the example
<presetdef name="my.javac">
<javac debug="${debug}" deprecation="${deprecation}"
srcdir="${src.dir}" destdir="${classes.dir}">
<src path="${gen.dir}"/>
</javac>
</presetdef>
Instead of my.javac, you can put javac.
You can define this in one build file and import every where else.

Build and deploy a Zend Framework PHP application in Jenkins

I'm setting up a jenkins job to build and deploy a Zend Framework 2 php application.
In my ant build script I've defined a lint job for validating php files.
The build job failed because lint detected an error in a ZF2 library file.
This is the output generated by lint:
[apply] PHP Fatal error: Constructor Zend\Captcha\Factory::factory() cannot be static in /var/lib/jenkins/workspace/XXX/vendor/zendframework/zendframework/library/Zend/Captcha/Factory.php on line 90
[apply] Errors parsing /var/lib/jenkins/workspace/XXX/vendor/zendframework/zendframework/library/Zend/Captcha/Factory.php
Does anybody know why the validation of Zend/Captcha/Factory.php fails ?
The ANT Task looks like this:
<target name="lint" description="Perform syntax check of sourcecode files">
<apply executable="php" failonerror="true">
<arg value="-l" />
<fileset dir="${basedir}/">
<include name="**/*.php" />
<modified />
</fileset>
<fileset dir="${basedir}/tests">
<include name="**/*.php" />
<modified />
</fileset>
</apply>
</target>
Your problem is because Zend Framework requires php 5.3.3 or later. Since your Jenkins box uses 5.3.2, this give a variety of problems. One of them is apparently the error you have now.
I think you haven't noticed the error before because on the development system you have a 5.3.3+ install. Try to update your testing environment to a newer version of php, that will remove this particular problem.
Update
To clarify my answer a bit, there is one backwards compatibility break in php 5.3.3 which comes back in your environment. Check this changelog and particularly this statement:
Backwards incompatible change:
Methods with the same name as the last element of a namespaced class name will no longer be treated as constructor. This change doesn't affect non-namespaced classes.
<?php
namespace Foo;
class Bar {
public function Bar() {
// treated as constructor in PHP 5.3.0-5.3.2
// treated as regular method in PHP 5.3.3
}
}
?>
There is no impact on migration from 5.2.x because namespaces were only introduced in PHP 5.3.
In the case of Zend\Captcha\Factory, there is a method factory() which is static so you can call Zend\Captcha\Factory::factory(). On php 4 and 5 up to 5.3.2, this method is also parsed as the constructor for the factory. And constructors cannot be static.
A linter will give you a fatal error for this case.

Problems with Ant optional tasks SSHExec and SCP. Classpath issue?

I'm in the process of modifying an Ant script (currently in use from within MyEclipse) to work from the command line. I'm doing this so anyone can check out the project and build it without MyEclipse. The problem I'm running into is that MyEclipse includes the dependencies behind the scenes. It does this by looking at the workspace's Ant configuration and compiling the classpath based on the selected libraries in the preferences dialog. Long story short, I need to take those dependencies and make the script smart enough to include them on its own, without the help of MyEclipse.
The tasks that are giving me a headache are the sshexec and scp tasks. They are optional ant tasks that require a version of jsch to run. I removed jsch from MyEclipse's Ant classpath and added it to a lib folder in the project itself (lib/dev). MyEclipse immediately complained that the SSHExec class could not find the dependent class, com.jcraft.jsch.UserInfo which is part of jsch-0.1.44.jar.
I don't see a way to set the classpath for Ant from within the build script. I have the following code, which adds a path element to the script, but I don't think Ant uses this unless explicitly associated to a task or another element.
<path id="web-jars">
<fileset dir="${web-lib}">
<include name="**/*.jar" />
</fileset>
<fileset dir="${app-lib}"> <!-- this is where jsch resides -->
<include name="**/*.jar" />
</fileset>
</path>
It seems that I need to use taskdef to define the sshexec and scp tasks:
<taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec"
classpathref="web-jars"/>
MyEclipse complains about this, "taskdef A class needed by class org.apache.tools.ant.taskdefs.optional.ssh.SSHExec cannot be found: com/jcraft/jsch/UserInfo"
It's clearly in the classpathref, web-jars. And I can't run anything in the script because of this malformed or misconfigured taskdef.
The problem here is that the SSHExec class is loaded from a classloader which itself has no access to your web-jars class loader. Supplying this classpath for the taskdef does not change this. Each class can only load classes from its own classloader and any parent class loaders, but the web-jars classloader is not a parent class loader of SSHExec's class loader (it is likely the other way around, since SSHExec seems to be found here).
It looks like this:
ClassLoader web-jars -------------> application CL -------------> bootstrap CL
taskdef
=> look for SSHExec here
=> look first in parent class loader
=> look for SSHExec here
=> look first in parent class loader
=> look for SSHExec here
=> not found
=> look in our own classpath
=> found, load the class
=> it somehow uses interface UserInfo
=> look for UserInfo here
=> look first in parent class loader
=> look for UserInfo here
=> not found
=> look in our own classpath
=> not found, throw exception.
The VM has no idea to look for UserInfo (and the other JSch classes) in the web-jars classloader.
I suppose the SSHExec task is somewhere in the usual ant classpath, i.e. loaded by the application class loader. Then removing SSHExec from ant's classpath (or adding jsch.jar to it) seems to be the only solution here.
Create ~/.ant/lib and copy jsch.jar in there as part of the build initialisation. Any tasks which do scp/sshexec work should depend on this init target.
<target name="init">
<property name="user.ant.lib" location="${user.home}/.ant/lib"/>
<mkdir dir="${user.ant.lib}"/>
<copy todir="${user.ant.lib}">
<fileset dir="${basedir}/build/tools" includes="jsch-*.jar"/>
</copy>
</target>
<target name="mytarget" depends="init">
<scp todir="user#host"><fileset dir="..."/></scp>
</target>
The Ant within Eclipse unfortunately won't pick this up immediately as it does not read ~/.ant/lib on every execution; After running mytarget within Eclipse once and watching it fail, then go to:
Window>Preferences>Ant>Runtime and press Restore Defaults - this will add any .jar files from ~/.ant/lib to the Global Entries section and you should be good to go.

Resources