Java Orchestration - java

I got 5 different .JAR's that I want to "run" with Apache Ant. I would like to give each of them some kind of "Order"-ID, (1 to 5) and have one JAR that runs all the other fives if they are selected.
Example: Component1, Component2, Component3, Component4, Component5 should be in the folder "job". I got a file called order.properties which looks like this: ComponentA = true, ComponentB = false and so on. Main.Jar should read order.properties and run all the Components that are "true" in the order that they are listed in the properties file.
I don't have any clue if thats possible and how because I simply don't know where to start looking for.

Yes, you can run tasks.
<java classname="test.Main">
<arg value="-h"/>
<classpath>
<pathelement location="dist/test.jar"/>
<pathelement path="${java.class.path}"/>
</classpath>
</java>
https://ant.apache.org/manual/Tasks/java.html

Related

How to reference other project with ANT?

I'm creating my build.xml and it works fine to generate the .war file.
But there's a small problem: I have got three projects: A, B and C. The project A (that I'll deploy with ANT) uses the classes of project B and C.
Then I just need a way so that when A is compiled it includes the project B and C as libs...
Is there some way to do that?
You can define a path with a pathelement for each jar file you need to include, and then include it as a classpath reference in your compile step.
For instance, if I define dependenciesClassPath like this:
<path id="dependenciesClassPath">
<pathelement path="${some.lib.dir}/ProjectB.jar"/>
<pathelement path="${some.lib.dir}/ProjectC.jar"/>
</path>
then I can include it in my compile target like so:
<javac destdir="${targetDir}/classes" source="1.7" target="1.7" debug="true">
<src refid="baseSourcePath"/>
<classpath refid="dependenciesClassPath"/>
</javac>

windows classpath issue with ant and java

I've been fighting in these trenches for a while now and have yet to get this working. Using many examples here on SO as well as others like this blog or this SO post, I still cannot get past the windows classpath limit. I'm currently just dealing with an ant task that runs a single main method in a java class within my source. If I can get this working here, I can extrapolate elsewhere.
First, my original relevant build tasks
<path id="code.classpath">
<path id="code.classpath">
<path refid="jars.code"/>
<path refid="jars.common"/>
<path refid="jars.servlet-api"/>
<dirset dir="${code.dir}" excludes="xlib/scripts/**"/>
</path>
<target name="code.exec" description="Execute a class file">
<echo>${code}</echo>
<input addproperty="code.exec.class">Enter full class name (e.g. ${atmr.pkg}.FooBar):</input>
<input addproperty="code.exec.args">Enter arguments:</input>
<java classname="${code.exec.class}"
fork="true"
dir="${code.src.dir}"
failonerror="true"
classpathref="code.classpath">
<jvmarg value="-Xmx4048M"/>
<jvmarg value="-ea"/>
<jvmarg value="-Dlog4j.configuration=file:${basedir}/log4j.xml"/>
<syspropertyset refid="proxy.properties"/>
<assertions refid="code.exec.assertions"/>
<arg line="${code.exec.args}"/>
</java>
</target>
Next, my most recent attempt at a solution
<path id="code.source">
<dirset dir="${code.dir}" excludes="xlib/scripts/**"/>
</path>
<target name="code.classpath.acme">
<manifestclasspath property="jar.classpath" jarfile="${app.dir}/acme.jar">
<classpath refid="code.source"/>
</manifestclasspath>
<jar destfile="${app.dir}/acme.jar" index="true">
<manifest>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</jar>
</target>
<path id="temp.classpath">
<pathelement path="${app.dir}/acme.jar"/>
</path>
<target name="code.exec" description="Execute a class file" >
<property name="myclasspath" refid="temp.classpath"/>
<echo>${code}</echo>
<echo>${basedir}</echo>
<echo>${myclasspath}</echo>
<input addproperty="code.exec.class">Enter full class name (e.g. ${atmr.pkg}.FooBar):</input>
<input addproperty="code.exec.args">Enter arguments:</input>
<java classname="${code.exec.class}"
fork="true"
dir="${code.src.dir}"
failonerror="true"
classpathref="temp.classpath">
<jvmarg value="-Xmx4048M"/>
<jvmarg value="-ea"/>
<jvmarg value="-Dlog4j.configuration=file:${basedir}/log4j.xml"/>
<syspropertyset refid="proxy.properties"/>
<assertions refid="code.exec.assertions"/>
<arg line="${code.exec.args}"/>
</java>
</target>
Basically, when running the first one, I get the "classpath is too long" issue in windows. Running the second one, I get "could not find or load main class package.classname." I've gone through the MANIFEST.MF that is created in the jar and the package location is present. From here went my travels down the rabbit hole to find what could be up. I've tested different permutations of the manifest relative locations to no avail. I've even gone in and manually changed the manifest to an explicit file location (not relative to the jar) with no change in results.
To confirm that the overall code works, I can add my code.dir path into temp.classpath and get the too long error. I can also make the acme jar build with the classes within it and get past the issue with the missing class.
Everywhere I read, this should work. Yet, here I am. I know that if the reference in the manifest can't be found, it silently skips it. That is what it seems to be doing, yet I've tried everything to get it to see what's there to no avail. And thus, I turn to you SO contributors to either point out the silly mistake I've missed, or let me in on the secret knowledge that I have yet to learn.
Thanks in advance.
You were perhaps closer with your original answer if you can at least achieve 'classpath is too long' answer.
Have you tried nesting your paths in order to make them 'relevant' rather than 'absolute' and thus shorter? perhaps using an alias such as the way you might list 'JAVA_HOME' in your PATH variable?
A way to test this quickly from the command line would be to edit the classpath and be sure to clear it out when you try to re-set it in code. In windows that would look like the following:
C:\WINDOWS>setx CLASSPATH "CLASSPATH;C:\some_new_path"
This will update the PATH by appending the new path to the existing path value. Typing the following command will print the new PATH in all future CMD windows; NOT in the current CMD window:
C:\WINDOWS>CLASSPATH
Typing the following will give you a list of all the environment variables:
C:\WINDOWS>set

Apache Ant {Compile javac srcdir} does not exist

I am new to apache ant and I am currently working on an apache Ant project. I Just started out, imported the project into workspace and tried to run the build.xml. I added all the libraries that come with the original project to the build path. I am having the following problem. Please someone else wrote the code and I am supposed to improve it. The directories this is all about exist in the project directory.
BUILD FAILED
C:\workspace\MyApp\build.xml:83: srcdir "C:\workspace\MyApp\${compile.javac.srcdir}" does not exist!
The error code is referencing the following part of the build.xml file
<target name="compile.default" depends="init">
<javac fork="yes" srcdir="${compile.javac.srcdir}" destdir="${compile.javac.destdir}" includes="${compile.javac.include}" excludes="${compile.javac.exclude}" classpath="${compile.javac.classpath}" debug="${compile.javac.debug}" optimize="${compile.javac.optimize}" deprecation="${compile.javac.deprecation}" verbose="${compile.javac.verbose}">
</javac>
<copy todir="${compile.javac.destdir}">
<fileset dir="${compile.javac.srcdir}" includes="${compile.copy.include}" excludes="${compile.copy.exclude}"/>
</copy>
</target>
<target name="compile" depends="init,compile.default" description="Compile all java source">
</target>
<!--+++++++++++++++-->
<!-- lib target(s) -->
<!--+++++++++++++++-->
<target name="lib.default" depends="init,compile">
<xmlbean schema="config/schemas/validate/1.0/validate.xsd" destfile="lib/glx-beans.jar" classpath="lib/xbean.jar:lib/jsr173_1.0_api.jar" />
<jar jarfile="${lib.filename}">
<fileset dir="${lib.srcdir}" excludes="${lib.exclude}" />
</jar>
</target>
<target name="lib" depends="init,compile,lib.default" description="Create all Project Libraries">
</target>
Would you please tell me what I am missing?
The ${compile.javac.srcdir} isn't defined. There are a few possibilities:
This is defined not in the build.xml, but in some sort of properties file. See if you have something like <property file="..."/> in your build script. My recommendation is to have all properties defined in the build.xml file, and use a properties file to override those settings. This way, the only build file that a developer needs in the build.xml file and doesn't have to worry about setting up a separate build.porperties file.
This is defined in the build.xml file under a particular task, but you forgot to say that your target where you use thisis dependent upon this task.
One of the things you can do is use the -d parameter when running Ant. I run the following command when running Ant with the -d parameter:
$ and -d 2>&1 | tee ant.out
I can then look at ant.out and see if somehow I didn't define that particular property. Maybe I had the wrong capitalization or misspelled the property name. For example, it's very likely I'll define the property as copmile.javac.srcdir because I don't know how to spell. Looking at the -d output can quickly point these types of errors out.
By the way, you shouldn't have all of your tasks dependent upon init since they're dependent upon compile.default anyway:
<target name="compile.default" depends="init">
....
</target>
<target name="compile" depends="compile.default">
....
</target>
<target name="lib" depends="compile,lib.default">
....
</target>
If I run the target lib, it will see compile is dependent upon compile.default which is dependent upon init. Thus, your build will run init, then compile.default, then compile, then 'lib.defaultand finallylib`.
If the init task is just setting up properties, you can do that outside of any task. Then, these properties will be setup before any task is executed. This way, they're not forgotten. If your init is also creating directories, you may want to move those <mkdir/> tasks in front of the task where that directory is used. For example, you may want to make the destdir uses in javac before the <javac/> task.
I find assigning default properties outside of any task, and creating directories before they are needed to simplify the build.xml. Plus, you're not creating a whole flock of unused directories if the user is merely compiling and not packaging the jar/war/etc.

How to bring the build process to an end when one of the target uses java ant with fork set to true

I have three targets of which one is using java as shown below
// Target that has java task
<java classname="org.apache.catalina.startup.Bootstrap" fork="true" classpathref="tomcat.class.path">
<jvmarg value="-Dcatalina.home=${build.tomcat.dir}" />
<arg line="start" />
</java>
My main target depends on the above target which has this java ant. The problem is everything works fine... this java ant starts my tomcat server and the control is not moved to the next target. Build.xml will be in running state.
How do I make the control move to the next targer once the target with java ant is done with the execution.
I have used parallel with daemons element and it worked fine... started the server and the control moved the next target. But the problem here is once I see a message in the console that server is up and when I try to access tomcat, it is up and running. Once the entire build is done and Build Successful message is displayed then again if I try to access tomcat, I do not see it up and running.
Any help please...
Thanks,
Try setting spawn = "true"
<java classname="org.apache.catalina.startup.Bootstrap" fork="true" spawn="true" classpathref="tomcat.class.path">
<jvmarg value="-Dcatalina.home=${build.tomcat.dir}" />
<arg line="start" />
</java>

What is the difference between the <pathelement> attributes 'path' and 'location' in Ant?

I was running Selenium unit tests in TestNG with the Ant Java task like so:
<java classpathref="runtime.classpath"
classname="org.testng.TestNG"
failonerror="false">
<arg value="-d" />
<arg value="${grid.location}/target/reports" />
<arg value="${lib.location}/testng.xml"/>
</java>
runtime.classpath is a pathlike structure that included <pathelement path="${basedir}/target/classes/" />, which I thought was needed to let TestNG know which classes to run.
<path id="runtime.classpath">
...
<!-- Target classes -->
<pathelement path="${basedir}/target/classes/" />
</path>
However, I kept seeing in the log that TestNG found 0 applicable classes.
I eventually got some help from a colleague and it appears this was the key change:
<path id="runtime.classpath">
...
<!-- path attribute changed to location -->
<pathelement location="${basedir}/target/classes/" />
</path>
This also pulls in the test classes correctly:
<java classpathref="runtime.classpath"
classname="org.testng.TestNG"
failonerror="false">
<arg value="-d" />
<arg value="${grid.location}/target/reports" />
<arg value="${lib.location}/testng.xml"/>
<classpath>
<pathelement location="${basedir}/target/classes/" />
</classpath>
</java>
What is the difference between the path and location attributes? I've looked at Writing a Simple Buildfile (specifically the Path-like Structures section), but in that manual it looks to me like location is more specific than path. That doesn't appear to be the case empirically, but I can't quite figure out why.
It looks like the difference between path and location is many entries vs one. A location is a file or directory, a path can be a list.
From the manual
The location attribute specifies a single file or directory relative
to the project's base directory (or an absolute filename), while the
path attribute accepts colon- or semicolon-separated lists of
locations. The path attribute is intended to be used with predefined
paths - in any other case, multiple elements with location attributes
should be preferred.
Note that the JVM used by ant has just about no relation to the JVM used by the java task. By default the environment of ant isn't the same as that of things started with the java task via ant. This is actually helpful when you want to use a different JVM from the one ant wants to use and makes things explicit, helping avoid surprises later on.
Check out the docs for the java task, particularly clonevm
clonevm: If set to true, then all system properties and the
bootclasspath of the forked Java Virtual Machine will be the same as
those of the Java VM running Ant. Default is "false" (ignored if fork
is disabled). since Ant 1.7

Categories

Resources