I'm executing an ant task inside my maven pom files to code generation purposes. (the code-generation tool is wsdl2java). during the process I fork new java process and pass the class path along with wsdl.
this works fine in the unix environment. but windows gives error saying ;
CreateProcess error=87, The parameter is incorrect.
this is because I'm passing the parameter maven.dependency.classpath as the classpath of the codegen tool. I have figured out that if there is a way to construct my custom classpath, using maven, that would solve my problem. (instead of giving a classpath includes all the jars in the maven repo).
maven-dependency-pluing:build-path goal seems to be promising, but i can specify the exact jars i want to include in my new classpath.
i have to include the class path variable in a root, pom so that other modules can use it.(lots of them)
I could find a way with maven-dependency-plugin:copy goal. but that it is a performance hit.
appreciate any help.
thanks in advance.
I could not find a way to build a classPath using dependency or any other maven plugin. The only option was to create a custom classPath and use it while java execution.
<path id="custom.classpath">
<pathelement location="location of the jar file"/>
</path>
And you refer the constructed classpath later in the java process execution.
<java className = "org.myClass">
<classpath refid="custom.classpath"/>
</java>
Hope this helps.
Related
I'm inheriting a project I need to maintain and trying to get the Ant deployment to Tomcat working on my localhost. When I run the deploy task, I get the following errors:
BUILD FAILED
/.../build.xml:69: Problem: failed to create task or type deploy
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.
I've tried looking around at others having the same problem, and found that commonly issues were in relation to CLASSPATH and missing catalina-ant.jar.
I added catalina-ant.jar to a folder in my project, called lib-exec, and inside my build.xml, these jars are loaded with:
<path id="project.classpath">
<fileset dir="${libDirectory}" includes="**/*.jar" />
<fileset dir="${extLibDirectory}" includes="**/*.jar" />
</path>
and ${extLibDirectory} is defined as:
<property name="extLibDirectory" location="ext-lib" />
My setup is as follows:
MAC OS X 10.8.4
Tomcat 7.0.42.0 (installed via Homebrew)
Java 1.6.0_51
Apache Ant 1.8.4
I tried running the ant deploy task from the command line, and also added
export CLASSPATH=$CLASSPATH:/usr/local/Cellar/tomcat/7.0.42/libexec/lib
to *~/.bash_profile* to attempt to include catalina-ant.jar this way, but nothing seems to work.
Any ideas what I'm messing up?
In addition to including the Tomcat classes in the Ant classpath, you need to define the "deploy" task to have Ant recognize it in the build.xml file, using the taskdef task (place it at the top of build.xml).
Defining paths and properties inside build.xml is completely irrelevant to the classpath (when build.xml is processed the JVM is already running).
Putting a folder in the classpath is likely useless (you need to include in the classpath the jar archives in that folder instead).
Moreover, there's no guarantee that Ant cares for the CLASSPATH environment variable; you have to inspect, and possibly change, the Ant launch script.
I just whipped up a medium-sized utilities JAR to be used by many other Eclipse projects. I spent a good deal of time writing tedious javadocs so that it would be pretty obvious how to use the API.
I used Ant to throw everything in a JAR, and I am now adding that JAR to the build path of a new project. But low and behold...when I mouseover any of my utility classes/methods, the tool tip that pops up says:
Note: this element neither has attached source nor attached Javadoc
and hence no Javadoc can be found.
What is going on here? What's the solution? Here is the dist Ant target that JARs up my utilities project:
<target name="dist" depends="compile">
<jar jarfile="dist/testing-utils.jar">
<fileset dir="bin/main" />
<fileset dir="src/main/config" />
</jar>
</target>
What else do I need to configure?!? Thanks in advance!
The java compile task, which I assume you're using in the "compile" target, generates bytecode from your Java source. This bytecode will not include comments by design and thus your distribution jar will not include comments.
What you are probably looking for is to attach the source in Eclipse to get access to the Javadocs. You can attach source to your library jars by right clicking on the target jar, selecting properties, select Java Source Attachment and provide the location of the source jar. You can also provide a folder location, if you want to reference your project directly.
To generate a Jar that includes javadocs and source, you may use the following in ant:
<target description="bundle sources in a jar" name="package-sources">
<jar basedir="src" destfile="build/release/${ant.project.name}-${project.version}-sources.jar"/>
</target>
Reference
If you do want to ship sources then johncarl's answer is probably correct; it is the first of the two options offered by eclipse -- attached sources. If you don't want to ship sources then you need to generate javadocs, see the ant javadoc task. With that approach, you would have two jars, one containing the compiled classes and another containing documentation. In eclipse, your users will add the class jar to project and then attach to it the javadoc jar.
My Java application has got a package structure similar to this:
src/com/name/app
src/com/name/app/do
src/com/name/utils/db
How would I go about compiling Java files in these directories in to a runnable jar? I need to package required libraries into the generated JAR (jdbc).
I've always done these things in Eclipse but now I need to supply a couple of people with a way to compile the repository without the use of eclipse and I was thinking of making a makefile or a script that invokes the necessary javac pattern.
Take a look at Ant. It's a relatively simple build tool to understand, and provides everything that meets your requirements. Here's a quick skeleton build.xml to get you started:
<project name="my_app_name" default="jar">
<target name="compile">
<javac srcdir="src" destdir="bin">
<classpath>
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</classpath>
</javac>
</target>
<target name="jar">
<jar manifest="manifest_file" destfile="dist/my_app_name.jar">
<fileset dir="bin" />
<fileset dir="lib" />
</jar>
</target>
You need to create a manifest file that will tell the java process which class holds the "main" method. Here is a good place to start learning about manifests.
As an alternate that produces really cluttered Ant build files, you can right click on your Eclipse project and choose "Export...", then choose "General > Ant Buildfiles".
Anyway, that should get you started. You can ask more specific questions as you run into them.
First of all, consider using Ant for such a task.
But since you asked for a manual process, you need to first create a manifest file, like so:
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Class-Path: lib/jdbc.jar lib/otherlib.jar
Main-Class: com.name.app.MainClass
Replace the contents of Class-Path with your libs, and Main-Class with the fully qualified name of your main class.
Then, you need to generate the actual .jar, using the following command:
jar cfm app.jar MANIFEST.MF src/com/name/app/*.class src/com/name/app/do/*.class
Where MANIFEST.MF is the previously mentioned manifest file, and the rest is the folders where your .java classes lie in.
Finally, to run your app, you simply execute: java -jar app.jar.
Consider using Ant to do this. http://ant.apache.org/
I recommend that you use Apache Ant to implement your build scripts.
If implemented correctly, Ant is easy to use and the build scripts can be run on any platform that you can install a JDK on. Indeed, with a little bit of work, you can even set up your project so that users don't even need to download / install Ant. (Hint: add the Ant JAR files and a wrapper script to your project distro)
I have a project that uses ant to build and ivy for dependencies. I would like to generate the start scripts for my project, with the classpath, based on the dependencies configured in Ivy, especially as the order of dependencies may be important and needs to be preserved from the order in the ivy config.
Has anyone done this before? I also need to generate relative paths in the classpath so I can't use absolute paths as this will only work for the machine on which the build is done.
EDIT: Based on feedback if we cut Ivy out the equation (do the resolve to a directory of my choice) I can then probably resolve the list of libs ok. But how would I generate a classpath suitable for a start script, especially with the relative paths (relative to my bin directory)?
e.g.
install
/bin <-- scripts here
/lib <-- jars here
So in my bin/start.sh I need to have ../lib/ in front of every jar reference rather than a full absolute path.
Thanks.
Since many years (2000?), we had this small script in path ("make_cp")
#!/usr/bin/perl
my $CLASSPATH="";
my $DIR=shift;
$DIR||="lib";
opendir(LIBDIR, $DIR);
while ($file = readdir(LIBDIR)) {
$CLASSPATH.=":$DIR/$file" if ($file =~ /\.jar$|\.zip$/);
}
closedir(LIBDIR);
$CLASSPATH=~ s/^://g;
print "$CLASSPATH";
Used like this:
export CLASSPATH=`make_cp lib`:`make_cp external-lib`
Since Ivy evicts overlapping dependencies and tries to find the best common dependency for all the projects I don't really understand how the order of dependencies would matter at all.
However you should make a standard JAR/WAR/other with Ant for your project and include Ivy dependencies inside that JAR. Basically all you should need to do is to make Ivy's Ant task to resolve the dependencies to a folder, then build tha classes using those dependencies and then consruct the JAR so that you include the library JAR:s to newly created JAR's /lib/ folder.
Like Esko said, you should create a JAR including all required JAR archives:
<zip destfile="abc.jar">
<zipgroupfileset dir="lib/distributed" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="com.acme.MyClass"/>
</manifest>
</zip>
After that, your start script is simply:
java -jar abc.jar
If you're using java 1.6 you can use file globs (i.e. java -cp "../lib/*"). If you're using an earlier version of java and you don't want to use Vladimir's solution, you'll need to write a script that figures out what the classpath should be.
So launch.sh looks something like:
cd dirname %0 # change to the bin directory, use %0/.. instead and you can replace ../lib with just /lib
sh set_classpath.sh # set the classpath
java -cp $CLASSPATH some.package.Main
and set_classpath.sh will have some linux magic that sets CLASSPATH equal to something like "../lib/abc.jar:../lib/def.jar"
export CLASSPATH=`ls *.jar | sed 's/[^.jar].jar/..\/lib\/\0:/'`
When receiving a bug report or an it-doesnt-work message one of my initials questions is always what version? With a different builds being at many stages of testing, planning and deploying this is often a non-trivial question.
I the case of releasing Java JAR (ear, jar, rar, war) files I would like to be able to look in/at the JAR and switch to the same branch, version or tag that was the source of the released JAR.
How can I best adjust the ant build process so that the version information in the svn checkout remains in the created build?
I was thinking along the lines of:
adding a VERSION file, but with what content?
storing information in the META-INF file, but under what property with which content?
copying sources into the result archive
added svn:properties to all sources with keywords in places the compiler leaves them be
I ended up using the svnversion approach (the accepted anwser), because it scans the entire subtree as opposed to svn info which just looks at the current file / directory. For this I defined the SVN task in the ant file to make it more portable.
<taskdef name="svn" classname="org.tigris.subversion.svnant.SvnTask">
<classpath>
<pathelement location="${dir.lib}/ant/svnant.jar"/>
<pathelement location="${dir.lib}/ant/svnClientAdapter.jar"/>
<pathelement location="${dir.lib}/ant/svnkit.jar"/>
<pathelement location="${dir.lib}/ant/svnjavahl.jar"/>
</classpath>
</taskdef>
Not all builds result in webservices. The ear file before deployment must remain the same name because of updating in the application server. Making the file executable is still an option, but until then I just include a version information file.
<target name="version">
<svn><wcVersion path="${dir.source}"/></svn>
<echo file="${dir.build}/VERSION">${revision.range}</echo>
</target>
Refs:
svnrevision: http://svnbook.red-bean.com/en/1.1/re57.html
svn info http://svnbook.red-bean.com/en/1.1/re13.html
subclipse svn task: http://subclipse.tigris.org/svnant/svn.html
svn client: http://svnkit.com/
Use the svnversion command in your Ant script to get the revision number:
<exec executable="svnversion" outputproperty="svnversion" failonerror="true">
<env key="path" value="/usr/bin"/>
<arg value="--no-newline" />
</exec>
Then use the ${svnversion} property somewhere in your EAR. We put it in the EAR file name, but you could also put it in a readme or version file inside the EAR, or specify the version in the EAR's META-INF/manifest.mf:
<!-- myapp-r1234.ear -->
<property name="ear" value="myapp-r${svnrevision}.ear" />
You'd want to provide the Subversion branch and repository number. As discussed in How to access the current Subversion build number?, the svn info command will give you this information, which you can then use to build a VERSION file or place in any of the other files that you're building into your *AR files. If you've nothing else in mind, you could consider using the XmlProperty Ant task to extract the relevant information from the output of your
svn info --xml command
Check out the jreleaseinfo project. Contains a ANT task that can generate a java class that can be called at runtime to display the release info for your project.
I like its simplicity.
See also this question: Build and Version Numbering for Java Projects (ant, cvs, hudson)
It includes several helpful code snippets.
From the top of my mind. A tag for each jar build?
We have the first part of our build create a version.txt file in the root of the package and dump the tag used to check the code out from (in our case) CVS... Additionally, the final part of our build process checks the fully built EAR back into CVS for future reference.
That way, if we have an issue with a webapp - it's just a case of asking the reporter to hit /app/version.txt - from there we can drill down the particular build history in CVS to locate the relevant components (handles different versions of libraries in apps) to locate the error.
Not sure how much help this is to our support folk - but it's definitely something they complain about not being there!
Do automatic builds, and place a tag (with a date stamp) on the codebase when the build is succesful (with unittest ofcourse).
In your delivery process, only deliver tagged builds to the customer. This way you are in control, and can place the tag name in a readme.txt somewhere, or have the filename of the ear file reflect the tagname.
I personally switched back to CVS, and this is one of the reasons. In CVS, I can have a class report it's tag. All my jar files contain a "main" which makes them runnable. With support questions, I ask the customer to do a "java -jar somejar.jar" and send the output to me alongside the question.
This way I'm sure of the build they-re using, and I can even have information like java version, OS type and version. Without the customer having to answer strange questions.
It's simple but very effective.
Why not put the build number into a properties file... this can then be easily read by the java and output to a Help | About dialog (applet/application), web-page footer or whatever other GUI you might have.
(See the footer on every SOF page.... has the SVN version number there.)
Seems a load easier than looking in the WAR/EAR/JAR etc easy time?
I store the absolute repository revision as a part of my full version number. This gives people a quick glance to see if a given change is in a given version or not.
We also store the version number / build date / etc in the manifest file of the ear as custom properties, these are mostly informational only. We also store it in a properties file that is built into our jar, so the application can read it.