Finding jdbc driver class problem with liquibase, ant - ant

Here is an example of my ant xml file:
<!--A reference to the classpath that contains the database driver, liquibase.jar, and the changelog.xml file-->
<path id="liquibase.classpath.id">
<pathelement location="${PROJECT_DIR}/lib/liquibase-2.0.2.jar"/>
<pathelement location="${jdbc.classpath}"/>
<fileset dir="${PROJECT_DIR}/db/changelog" includes="db.changelog*.xml"/>
</path>
<pathconvert refid="liquibase.classpath.id" property="liquibase.classpath.id.text" />
<echo message="${liquibase.classpath.id.text}" />
<updateDatabase loglevel="debug"
changeLogFile="${db.changelog.file}"
driver="${jdbc.driver}"
url="${jdbc.url}"
username="${database.username}"
password="${database.password}"
dropFirst="false"
classpathref="liquibase.classpath.id"
/>
I'm getting the following output from <echo message="${liquibase.classpath.id.text}" /> as expected:
G:\My Documents\PROJECTS\DataSource\lib\liquibase-2.0.2.jar;
G:\My Documents\PROJECTS\DataSource\lib\hsqldb-2.2.5.jar;;
G:\My Documents\PROJECTS\DataSource\db\changelog\db.changelog-1.0.xml;
G:\My Documents\PROJECTS\DataSource\db\changelog\db.changelog-master.xml
But updateDatabase throws the following exception:
java.lang.ClassNotFoundException: org.hsqldb.jdbc.JDBCDriver
What am I doing wrong? Please tell me.

I can't see where you're defining the value for jdbc.driver, but the class name should be org.hsqldb.jdbc.JDBCDriver, not org.hsqldb.jdbcDriver

Is that the name of hsqldb's driver? Docs I've seen show org.hsqldb.jdbc.JDBCDriver.

As already pointed out, the JDBC driver should be org.hsqldb.jdbc.JDBCDriver. I think your second problem is that ANT cannot find your hsqldb jar file. You absolutely sure the path is correct?
Here's my working example (I delegate classpath management to the ivy plug-in).
liquibase.properties
url=jdbc:hsqldb:file:build/testdb
driver=org.hsqldb.jdbc.JDBCDriver
username=sa
password=""
build.xml
<project basedir="." default="build" xmlns:ivy="antlib:org.apache.ivy.ant">
<!--
====================
Properties and paths
====================
-->
<property file="liquibase.properties" prefix="db"/>
<property name="build.dir" location="build"/>
<property name="db.changelog.file" location="src/scottTiger.xml"/>
<!--
=======
Targets
=======
-->
<target name="init" description="Download 3rd party dependencies">
<ivy:resolve/>
<ivy:cachepath pathid="ant.path" conf="ant"/>
<mkdir dir="${build.dir}"/>
</target>
<target name="build" depends="init" description="Create the database">
<taskdef resource="liquibasetasks.properties" classpathref="ant.path"/>
<fail unless="db.changelog.file">db.changelog.file not set</fail>
<fail unless="db.url">db.url not set</fail>
<fail unless="db.driver">db.driver not set</fail>
<fail unless="db.username">db.username not set</fail>
<fail unless="db.password">db.password not set</fail>
<updateDatabase
changeLogFile="${db.changelog.file}"
driver="${db.driver}"
url="${db.url}"
username="${db.username}"
password="${db.password}"
promptOnNonLocalDatabase="false"
dropFirst="false"
classpathref="ant.path"
/>
</target>
<target name="clean" description="Cleanup all built files">
<delete dir="${build.dir}"/>
</target>
<target name="clean-all" depends="clean">
<ivy:cleancache/>
</target>
</project>
ivy.xml
Build is configured to download the latest release versions, available from Maven Central
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="scott-tiger"/>
<configurations defaultconfmapping="ant->default">
<conf name="ant" description="Ant build dependencies"/>
</configurations>
<dependencies>
<dependency org="org.liquibase" name="liquibase-core" rev="latest.release"/>
<dependency org="org.hsqldb" name="hsqldb" rev="latest.release"/>
</dependencies>
</ivy-module>

Related

How to publish resolved ivy.xml to Nexus

My artifact is a text file with some text in it(commit id). Here is my ivy.xml and build.xml
ivy.xml
<ivy-module version="2.0">
<info organisation="org.myorg"
module="commit-info"
status="release"/>
<publications>
<artifact name="commit_info" type="text" ext="txt"/>
</publications>
</ivy-module>
build.xml
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="SuperRoot" default="prepare" basedir=".">
<property file="../release.properties"/>
<path id="ivy.lib.path">
<fileset dir="../lib" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant"
classpathref="ivy.lib.path"/>
<property name="organisation" value="org.myorg"/>
<property name="build.dir" value="."/>
<property name="ivy.dir" value="build/ivy"/>
<target name="init">
<mkdir dir="build"/>
<mkdir dir="build/ivy"/>
</target>
<target name="prepare" description="Generate POM">
<ivy:settings file="../ivysettings.xml" />
<ivy:retrieve />
<!-- Optional: Intermediate file containing resolved version numbers -->
<echo message="Using repo at ${repo.host} "/>
<ivy:deliver deliverpattern="${ivy.dir}/ivy.xml"
pubrevision="${publish.revision}"
status="release"/>
<!-- Generate the Maven POM -->
<ivy:makepom ivyfile="${ivy.dir}/ivy.xml"
pomfile="${build.dir}/pom.xml"/>
</target>
<target name="publish" depends="init,prepare" description="Upload to Nexus">
<ivy:resolve/>
<ivy:publish organisation="org.myorg" module="commit-info"
resolver="nexus-deploy"
pubrevision="${publish.revision}"
overwrite="true"
publishivy="false" >
<artifacts pattern="${build.dir}/[artifact].[ext]"/>
</ivy:publish>
</target>
</project>
ant publish creates and copy the files to my repository (Nexus). This does not copy "resolved" ivy.xml. How can I publish it?
Changing
publishivy="false"
to
publishivy="true "
solved that part.

when I run Ant in cmd it is showing me error of build.xml not exist while I have build.xml file in my project folder

I am a selenium user trying to generate xslt reports using Ant, but when I run Ant in cmd it is showing me error of build.xml not exist while I have build.xml file in my project folder.
I am using eclispe juno on windows 7 and and kept the build.xml file under the project.
I have java JDK1.7 on my machine and I have already set the environment variables(Java and ant both) as per instructions given on apache.org
Ant version is apache-ant-1.9.1
I have imported all necessary jar files (selenium + maven +saxon + all required for xslt report through ant) in my project in eclipse.
When I am trying to run ant through cmd it is showing me this error:-
BUILD FAILED
D:\Projects\Project\Selenium\Workspace\build.xml:70: Compile failed; see the compiler error output for details.
Below is my build.xml file:-
<project name="Plumslice" default="usage" basedir=".">
<property environment="env"/>
<property name="ws.home" value="${basedir}"/>
<property name="ws.jars" value="D:\All jars"/>
<property name="test.dest" value="${ws.home}/build"/>
<property name="test.src" value="${ws.home}/src"/>
<property name="ng.result" value="test-output"/>
<!--target name="start-selenium-server">
<java jar="${ws.home}/lib/selenium-server.jar"/>
</target-->
<target name="setClassPath" unless="test.classpath">
<path id="classpath_jars">
<fileset dir="${ws.jars}" includes="*.jar"/>
</path>
<pathconvert pathsep=":"
property="test.classpath"
refid="classpath_jars"/>
</target>
<target name="init" depends="setClassPath">
<tstamp>
<format property="start.time" pattern="MM/dd/yyyy hh:mm aa" />
</tstamp>
<condition property="ANT"
value="${env.ANT_HOME}/bin/ant.bat"
else="${env.ANT_HOME}/bin/ant">
<os family="windows" />
</condition>
<taskdef name="testng" classpath="${test.classpath}"
classname="org.testng.TestNGAntTask" />
</target>
<!-- all -->
<target name="all">
</target>
<!-- clean -->
<target name="clean">
<delete dir="${test.dest}"/>
</target>
<!-- compile -->
<target name="compile" depends="init, clean" >
<delete includeemptydirs="true" quiet="true">
<fileset dir="${test.dest}" includes="**/*"/>
</delete>
<echo message="making directory..."/>
<mkdir dir="${test.dest}"/>
<echo message="classpath------: ${test.classpath}"/>
<echo message="compiling..."/>
<javac
debug="true"
destdir="${test.dest}"
srcdir="${test.src}"
target="1.7"
classpath="${test.classpath}">
</javac>
<copy todir="${test.dest}">
<fileset dir="${test.src}" excludes="**/*.java"/>
</copy>
</target>
<!-- build -->
<target name="build" depends="init">
</target>
<!-- run -->
<target name="run" depends="compile">
<testng classpath = "${test.classpath}:${test.dest}" suitename = "suite1" >
<xmlfileset dir="${ws.home}" includes="testng.xml"/>
</testng>
<!--
<testng classpath="${test.classpath}:${test.dest}" groups="fast">
<classfileset dir="${test.dest}" includes="example1/*.class"/>
</testng>
-->
</target>
<target name="usage">
<echo>
ant run will execute the test
</echo>
</target>
<path id="test.c">
<fileset dir="${ws.jars}" includes="*.jar"/>
</path>
<target name="email" >
<java classname="com.qtpselenium.util.SendMail" classpath="${test.dest}" classpathref="test.c" />
</target>
<target name="makexsltreports">
<mkdir dir="${ws.home}/XSLT_Reports/output"/>
<xslt in="${ng.result}/testng-results.xml" style="src/com/testing/xslt/testng-results.xsl"
out="${ws.home}/XSLT_Reports/output/index.html" classpathref="test.c" processor="SaxonLiaison">
<param name="testNgXslt.outputDir" expression="${ws.home}/XSLT_Reports/output/"/>
<param name="testNgXslt.showRuntimeTotals" expression="true"/>
</xslt>
</target>
</project>
Thanks you all for your great help, I have resolved that error ..
It was related to the path of the jar files , I provided incorrect path to the jars.
This was line 70 : -
<javac debug="true" destdir="${test.dest}" srcdir="${test.src}"
target="1.7" classpath="${test.classpath}">
this is related to the path to the jars and in the top line of my file I did provided this path - D:\All jars , while all required jars was not in this folder, now I updated the jar folder and it is working fine now.

Ant With Internal Dependencies

I have a a jar right now that uses external dependencies. I'm trying to create a jar that packages all the external dependencies inside, and will just give me one jar. I saw this question asked multiple times, but I still can't figure it out. I'm using Ant, and copied some of the examples I saw on here. I'm using zipgroupfileset to reference the external(now internal) jars. As soon as I added the zipgroupfileset I got a runtime error that said my Runner class could not be found.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- WARNING: Eclipse auto-generated file.
Any modifications will be overwritten.
To include a user specific buildfile here, simply create one in the same
directory with the processing instruction <?eclipse.ant.import?>
as the first entry and export the buildfile again. -->
<project basedir="." default="build" name="ExcelDemo">
<property environment="env"/>
<property name="ECLIPSE_HOME" value="../../../../Program Files (x86)/eclipse"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>
<property name="external-lib-dir" value="lib\poi-3.9" />
<property name="external-lib-dir2" value="lib\poi-3.9\lib" />
<property name="external-lib-dir3" value="lib\poi-3.9\ooxml-lib" />
<path id="ExcelDemo.classpath">
<pathelement location="bin"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src" excludes="**/*.launch, **/*.java"/>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-subprojects,build-project" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="ExcelDemo.classpath"/>
</javac>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects">
<ant antfile="${ExcelSensitize.location}/build.xml" inheritAll="false" target="clean"/>
<ant antfile="${ExcelSensitize.location}/build.xml" inheritAll="false" target="build">
<propertyset>
<propertyref name="build.compiler"/>
</propertyset>
</ant>
</target>
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
<copy todir="${ant.library.dir}">
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</copy>
<unzip dest="${ant.library.dir}">
<patternset includes="jdtCompilerAdapter.jar"/>
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</unzip>
</target>
<target description="compile project with Eclipse compiler" name="build-eclipse-compiler">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<antcall target="build"/>
</target>
<target name="RunnerClass">
<java classname="runner.RunnerClass" failonerror="true" fork="yes">
<classpath refid="ExcelDemo.classpath"/>
</java>
</target>
<target name="jar" description="Create a jar for this project">
<manifestclasspath property="lib.list" jarfile="Test.jar">
<classpath refid="ExcelDemo.classpath" />
</manifestclasspath>
<jar jarfile="Test.jar" includes="*.class" basedir="bin">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<zipgroupfileset dir="${external-lib-dir2}" includes="*.jar"/>
<zipgroupfileset dir="${external-lib-dir3}" includes="*.jar"/>
<manifest>
<attribute name="Class-Path" value="${lib.list}" />
<attribute name="Main-Class" value="runner.RunnerClass" />
</manifest>
</jar>
</target>
</project>
To make things simpler:
Create a separate sources jar for compilation. Then, have a separate compiled jar without the sources.
Don't include the third party jars. Instead, use Ivy with Ant. Ant will automatically download the required jars. In fact, I've see sources that just include the ivy.jar, so Ivy will automatically be configured when you unjar the sources. You type in ant, and everything just builds.
As an alternative, you can look at Maven which is how many projects are now packaged. In fact, if your jar is an open source project, you can probably host it on the OSS Maven repository. This way, no one even needs to manually download your compiled jar. If they want it, they configure their Maven project to do it for them.
i think the problem is that you use basedir="bin" in the your jar task. then path of your zipgroupfileset convert to bin/${external-lib-dir}

Upload jar to nexus sonatype repo by using ivy and ant

I am trying to use ivy with ant to publish my project artifact to nexus sonatype repository.
Using three files:
1>-- build.xml
<project name="abc" basedir="."
default="create-jar" xmlns:ivy="antlib:org.apache.ivy.ant">
<property name="build.dir" value="classes"/>
<property name="src.dir" value="src"/>
<property name="webinf.dir" value="../WEB-INF"/>
<property name="weblib.dir" value="${webinf.dir}/lib"/>
<path id="master-classpath">
<fileset dir="${weblib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<target name="clean" description="Clean output dirs (build, weblib, dist)">
<delete dir="${build.dir}"/>
<mkdir dir="${build.dir}"/>
<delete dir="dist"/>
<mkdir dir="dist"/>
</target>
<target name="create-jar" depends="clean">
<javac destdir="${build.dir}" source="1.5" target="1.5" debug="true" deprecation="false" optimize="false" failonerror="true" nowarn="true">
<classpath refid="master-classpath"/>
<src path="${src.dir}"/>
</javac>
<jar destfile="dist/mws-pojos.jar" basedir="${build.dir}"/>
</target>
<target name="prepare" description="Generate POM" depends="create-jar">
<!-- Optional: Intermediate file containing resolved version numbers -->
<!--ivy:deliver deliverpattern="${build.dir}/ivy.xml" pubrevision="${publish.revision}" status="release"/-->
<!-- Generate the Maven POM -->
<ivy:makepom ivyfile="ivy.xml" pomfile="test.pom"/>
</target>
<target name="resolve" description="retreive dependencies with ivy"
depends="publish">
<ivy:retrieve />
</target>
<target name="publish" depends="prepare,create-jar"
description="Upload to Nexus">
<ivy:publish organisation="my.org" module="mws-pojos"
revision="1.0" resolver="nexus-deploy"
pubrevision="${publish.revision}"
overwrite="true" publishivy="false" >
<artifacts pattern="${build.dir}/[artifact](-[classifier]).[ext]"/>
</ivy:publish>
</target>
</project>
2--> ivy.xml
<ivy-module version='2.0' xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="my.org" module="mws-pojos" revision="1.0"/>
<publications>
<artifact name="mws-pojos" type="jar" e:classifier="disto"/>
</publications>
</ivy-module>
3--> ivysettings.xml
<ivysettings>
<settings defaultResolver="nexus-central"/>
<credentials host="http://somehost/nexus" realm="Sonatype Nexus Repository Manager" username="user1" passwd="deploy"/>
<resolvers>
<ibiblio name="nexus-central" root="http://somehost/nexus/content/repositories/central/" m2compatible="true"/>
<ibiblio name="nexus-deploy" root="http://somehost/nexus/content/repositories/repo" m2compatible="true"/>
</resolvers>
</ivysettings>
But on compillation it is giving following error :
BUILD FAILED
/home/someuser/mobilewebservice/mws-pojos/build.xml:40: impossible to publish artifacts for mmt#mws-pojos;1.0: java.lang.IllegalStateException: ivy file not found in cache for mmt#mws-pojos;1.0: please resolve dependencies before publishing (/home/someuser/.ivy2/cache/resolved-mmt-mws-pojos-1.0.xml)
at org.apache.ivy.core.publish.PublishEngine.publish(PublishEngine.java:105)
at org.apache.ivy.Ivy.publish(Ivy.java:600)
at org.apache.ivy.ant.IvyPublish.doExecute(IvyPublish.java:311)
at org.apache.ivy.ant.IvyTask.execute(IvyTask.java:277)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
You need an additional resolve
<ivy:resolve>...</ivy:resolve>
before publishing.

Does the junit.jar has to be in the ant lib directory to run junit task

I was building an Ant build file that worked properly in my eclipse project but not on our Jenkins autobuild set-up. I installed ant on my computer and ran the build from the console. It worked, but I realized it didn't use the junit-4.10.jar in my project lib like I wished but the junit.jar in the ant lib. After renaming the junit.jar files in my ant lib, the ant build didn't work.
So basically the problem in our Jenkins autobuild setup is that there are no junit.jar in its own ant lib directory. Can I specify the junit task to use the jar in my project lib instead of the one in the ant lib?
EDIT : I have modified my build.xml file and now it looks like this, still doesnt work. My junit-4.10.jar is in the /war/WEB-INF/lib/test directory :
<project name="vlp" default="junit" basedir=".">
<tstamp />
<!-- ################# PROPERTIES ################ -->
<!-- directory properties -->
<!-- source -->
<property name="vlp.src" location="src" />
<property name="vlp.test" location="test" />
<!-- build -->
<property name="src.build" location="bin/src" />
<property name="test.build" location="bin/test" />
<!-- libraries -->
<property name="vlp.lib.dir" location="war/WEB-INF/lib" />
<property name="vlp.testlib.dir" location="war/WEB-INF/lib/test" />
<!-- compile classpath -->
<path id="compile.path">
<fileset dir="${vlp.lib.dir}" includes="*.jar" />
</path>
<!-- test classpath -->
<path id="test.path">
<fileset dir="${vlp.testlib.dir}" includes="*.jar" />
<path refid="compile.path" />
</path>
<!-- ############### CLEANING ################## -->
<!-- Cleaning old compile files -->
<target name="clean" description="Clean all the old build files.">
<delete dir="${src.build}" />
<delete dir="${dist}" />
</target>
<!-- ############## COMPILATION ############### -->
<!-- Compile source -->
<target name="src.compile" depends="clean" description="Compile the source code when everything has been cleaned.">
<mkdir dir="${src.build}" />
<javac encoding="utf-8" destdir="${src.build}" nowarn="true">
<src path="${vlp.src}" />
<classpath refid="compile.path" />
</javac>
</target>
<!-- Compile test -->
<target name="test.compile" depends="clean" description="Compile the source code when everything has been cleaned.">
<mkdir dir="${test.build}" />
<javac encoding="utf-8" destdir="${test.build}" nowarn="true">
<src path="${vlp.test}" />
<classpath>
<pathelement location="${src.build}" />
<path refid="test.path" />
</classpath>
</javac>
</target>
<!-- ########### RUNS JUNIT TEST ############ -->
<target name="junit" depends="src.compile,test.compile" description="Runs all the unit test in the application. Does not halt build if test are failed.">
<junit printsummary="on" haltonfailure="false" showoutput="true">
<formatter type="brief" usefile="false" />
<classpath>
<pathelement location="${test.build}" />
<path refid="test.path" />
</classpath>
<batchtest>
<fileset dir="${vlp.test}">
<include name="**/Test*.java" />
<exclude name="**/AllTests.java" />
</fileset>
</batchtest>
</junit>
</target>
</project>
EDIT : Simlar question can be found here with a different answer that works well. Note that it is much easier to install ant-junit on the machine than to try to add it to your libs and everything.
See the answer to this question:
H2 database org.h2.Driver ClassNotFoundException
I normally specify the junit jar to be on a test classpath and then use it when calling the junit ANT task
Update
The following build file is an example of a starting template I used for my builds.
Sets up an infrastructure that uses ivy to manage classpaths. Dependencies are downloaded from the Maven Central repository (by default). Makes build much more portable and repeatable.
build.xml
<project name="ivy demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">
<!--
==========
Properties
==========
-->
<property name="build.dir" location="build"/>
<property name="class.dir" location="${build.dir}/classes"/>
<property name="report.dir" location="${build.dir}/reports"/>
<!--
=======
Targets
=======
-->
<target name="install-ivy" description="Used to install the ivy task jar">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.2.0/ivy-2.2.0.jar"/>
</target>
<target name="init" description="Download dependencies, setup project classpaths and create build directories">
<ivy:resolve/>
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="runtime.path" conf="runtime"/>
<ivy:cachepath pathid="test.path" conf="test"/>
<ivy:report todir="${report.dir}" graph="false"/>
<mkdir dir="${class.dir}"/>
</target>
<target name="build" depends="init" description="Build the project">
<echo message="Build logic goes here"/>
</target>
<target name="clean" description="Remove build directories">
<delete dir="${build.dir}"/>
</target>
<target name="clean-all" depends="clean" description="Purge ivy cache">
<ivy:cleancache />
</target>
</project>
ivy.xml
This file is used to specify the project's dependencies. Ivy configurations are used to manage the classpath groupings.
<ivy-module version="2.0">
<info organisation="org.demo" module="demo"/>
<configurations>
<conf name="compile"/>
<conf name="runtime" extends="compile"/>
<conf name="test" extends="runtime"/>
</configurations>
<!--
Dependencies can be found using Maven Central's search site:
http://search.maven.org/
-->
<dependencies>
<!-- Compile dependencies -->
<dependency org="org.slf4j" name="slf4j-api" rev="1.6.4" conf="compile->default"/>
<!-- Runtime dependencies -->
<dependency org="log4j" name="log4j" rev="1.2.16" conf="runtime->default"/>
<!-- Test dependencies -->
<dependency org="junit" name="junit" rev="4.10" conf="test->default"/>
</dependencies>
</ivy-module>

Resources