Reputation: 7934
I am trying to use the axis-java2wsdl ant task to create a wsdl from one of my java classes, but I cannot get the classpath correct.
I am using Ubuntu's libaxis-java package which installs axis-ant.jar in $ANT_HOME/lib and axis.jar in /usr/share/java. The interesting parts of my build.xml look like this:
<property name="library.dir" value="lib"/>
<property name="system.library.dir" value="/usr/share/java"/>
<path id="libraries">
<fileset dir="${library.dir}">
<include name="*.jar"/>
</fileset>
<fileset dir="${system.library.dir}">
<include name="*.jar"/>
</fileset>
</path>
<target name="genwsdl" depends="compile">
<taskdef resource="axis-tasks.properties" classpathref="libraries"/>
<axis-java2wsdl>
details omitted
</axis-java2wsdl>
</target>
Running ant genwsdl
results in:
/build.xml:50: taskdef A class needed by class
org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask
cannot be found: org/apache/axis/utils/DefaultAuthenticator
Ant is able to find the definition of the axis-java2wsdl task, because axis-ant.jar is in $ANT_HOME/lib, but it cannot find classes in axis.jar, even though that jar is on the path defined by "libraries"
I know it's a classpath issue because I was able to get past DefaultAuthenticator to other class's not found by symlinking axis.jar into $ANT_HOME/lib. How can I get the taskdef to recognize jar files in /usr/share/lib or my project's local lib directory without symlinking everything into $ANT_HOME/lib?
EDIT:
I was finally able to successfully generate the wsdl with this line:
ant -lib /usr/share/java/axis.jar -lib /usr/share/java/jaxrpc.jar -lib /usr/share/java/wsdl4j.jar -lib /usr/share/java/commons-logging.jar -lib /usr/share/java/commons-discovery.jar -lib build genwsdl
I would still very much appreciate if somebody could tell me what I'm doing wrong in not being able to define those libraries in build.xml
Upvotes: 15
Views: 99425
Reputation: 21
I met the same problem when I copy a *.jar to the {ant.home}/libs, then i user the -lib to locate the *.jar, it's runs ok! I consider it's the new jars can't be loaded, then i'll test it!
Upvotes: 0
Reputation: 11075
Using the answers from here and all the partial information, I came up with a solution. I added the jar the ant file needed to a lib folder in the project (specifically mysql jdbc drivers). Then I run a setup task in ant that copies to the user's home .ant/lib folder, and then fails ant with a message to restart. It only fails once for a user, and then works every time. It might be tricky if you update the jar to a new version...
Here's the ant build.xml:
<project name="data_source" default="build">
<!-- BUILD PROPERTIES -->
<property file="build.properties"/>
<!-- SQL Server Properties -->
<property name="sql.driver" value="org.gjt.mm.mysql.Driver"/>
<property name="sql.url" value="jdbc:mysql://127.0.0.1/datastore"/>
<property name="sql.user" value="user"/>
<property name="sql.pass" value="password"/>
<!-- FILE LOCATIONS -->
<property name="sql.dir" location="sql"/>
<!-- INITIALIZE PROJECT -->
<target name="init" description="Initialize the project">
<available property="no.ant.lib.dir" file="${user.home}/.ant/lib/" type="dir" />
</target>
<!-- SETUP MYSQL -->
<target name="setup_mysql" description="Copy the lib so ant can see it" unless="no.ant.lib.dir">
<mkdir dir="${user.home}/.ant"/>
<mkdir dir="${user.home}/.ant/lib"/>
<copy file="lib/mysql-connector-java-5.1.13-bin.jar" todir="${user.home}/.ant/lib"/>
<!-- ant already missed picking up the jar - we have to restart -->
<fail message="JDBC mysql class copied to ${user.dir}/.ant/lib/ - please restart ant" />
</target>
<!-- BUILD DATA SOURCES -->
<target name="build" depends="init,setup_mysql,clean_data" description="Create and populate tables">
<sql driver="${sql.driver}" url="${sql.url}" userid="${sql.user}" password="${sql.pass}" >
<transaction src="${sql.dir}/create_tables.sql"/>
<transaction src="${sql.dir}/insert_data.sql"/>
</sql>
</target>
<!-- CLEAN PROJECT -->
<target name="clean" description="Cleans up project build">
<!-- Don't clean data sources here - may get called by accident -->
</target>
<!-- Delete all tables and data -->
<target name="clean_data" description="Deletes all data and tables">
<echo>Dropping all database tables in ${sql.schema}...</echo>
<property name="exec.command" value="mysqldump -u${sql.user} -p${sql.pass} --add-drop-table --no-data ${sql.schema} | grep ^DROP | mysql -u${sql.user} -p${sql.pass} ${sql.schema}" />
<exec executable="sh">
<arg value = "-c"/>
<arg value="${exec.command}"/>
</exec>
</target>
</project>
Hope this helps
Upvotes: 1
Reputation: 14840
It works for me to specify the classpath directly in the taskdef task, as menstioned by matt b. For my project I find it useful to include the taskdef library in the project folder and specify the classpath in the ant build file, to simply setup on other development pcs. I use the following taskdef:
<taskdef resource="antenna.properties" classpath="${myprojectroot}/lib/antenna-bin-1.2.1-beta.jar"/>
Note that this might not work for versions of ant earlier than 1.7.0.
Upvotes: 1
Reputation: 139921
Why not just take the simplest option and specify the classpath in your <taskdef>
?
<taskdef resource="axis-tasks.properties">
<classpath>
<fileset file="/path/to/axis/jars"/>
</classpath>
</taskdef>
Or create a second <classpath>
entry that subsets library.dir
?
<path id="axis-tools-classpath">
<fileset dir="/path/to/axis/home">
<include name="*.jar"/>
</fileset>
<path refid="library.dir"/>
</path>
Messing around with ${ant.home}/lib
is not such a good idea and can almost always be avoided.
Upvotes: 1
Reputation: 1323115
In general, this works. But you need to check very carefully which classes are where.
If your task class can be loaded in a classloader higher up in the classloader hierarchy (like CLASSPATH or ANT_HOME/lib) then your classpathref will simply get ignored.
Read the FAQ entry for more details.
Ant's class loader implementation uses Java's delegation model
The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When called upon to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself. The virtual machine's built-in class loader, called the bootstrap class loader, does not itself have a parent but may serve as the parent of a ClassLoader instance.
Note: running ant -diagnostics
can help too.
Upvotes: 17
Reputation: 199195
Ant mechanism for adding libraries is:
Only. The manual doesn't mention anything about using the system.library.dir property. Probably it pretty much ignored for this purpose.
Also, run ant in verbose mode ( and -verbose ) to see what is doing under the hood.
Upvotes: 5