Home >
First, let’s look at how we’ll make an Ant build perform our data-related tasks, such as updating the schema and loading sample data. Then, we’ll see how Maven is configured to call Ant.
<project default="data-tasks" basedir="." name="Bookie Database Tasks">
<property name="maven.repo.local"
value="${user.home}/.m2/repository"/>
<property file="jdbc.properties.mysql" />
<property location="src/data" name="src.dir" />
<property location="${src.dir}/datasets" name="dataset.dir" />
<path id="maven.repo.classpath">
<fileset dir="${maven.repo.local}">
...lots of includes to jars...
</fileset>
</path>
Isn’t this defeating the purpose of Maven if we have to tell Ant about the dependencies too? Well, it is a bit of extra configuration, but at least Maven can make it easy for us by automatically generating the code for that part. It’s a little hackish, but it’s better than having separate JARs that Ant needs checked into the source control system and duplicated in the Maven repository. Here’s how to get the code generated for the includes.
First, use Maven’s Ant plug-in to generate a build file.
Note that you may want to copy the existing build.xml somewhere safe, because it will be overwritten. Just type `mvn ant:ant` in the bookie-data project and Maven will generate the equivalent of what it takes to build the project into an Ant build file named build.xml. Then, copy the section that includes all the libraries from the user’s Maven repository and paste it into the build file that does what you need to do. These are the steps I took, and because we only need to use DBUnit in our build file, we can get that part straightened out even before we build out other parts of the project with more dependencies. Figure 5 shows a screenshot of the process.
Now that that’s done, there are a few task definitions in the data project’s build.xml:
<taskdef name="ddlToDatabase" classname=
"org.apache.ddlutils.task.DdlToDatabaseTask">
<classpath>
<path refid="maven.repo.classpath"/>
</classpath>
</taskdef>
<taskdef name="databaseToDdl" classname="
org.apache.ddlutils.task.DatabaseToDdlTask">
<classpath>
<path refid="maven.repo.classpath"/>
</classpath>
</taskdef>
<taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask">
<classpath>
<path refid="maven.repo.classpath"/>
</classpath>
</taskdef>
These task definitions allow us to use DDLUtils and DBUnit in our Ant build.
<target
name="dump-schema"
description="Dumps the database schema"
depends="data-tasks">
<databaseToDdl modelName="bookie">
<database
url="${datasource.url}"
driverClassName="${datasource.driverClassName}"
username="${datasource.username}"
password="${datasource.password}" />
<writeSchemaToFile outputFile="${src.dir}/schema.xml"/>
databaseToDdl>
</target>
<target
name="load-schema"
description="loads schema from schema.xml"
depends="data-tasks">
<ddlToDatabase>
<database
url="${datasource.url}"
driverClassName="${datasource.driverClassName}"
username="${datasource.username}"
password="${datasource.password}" />
<fileset dir="${src.dir}">
<include name="schema.xml"/>
</fileset>
<writeSchemaToDatabase />
</ddlToDatabase>
</target>
These are the tasks to deal with keeping the database up-to-date. dump-schema writes the tables in the database to a file called schema.xml in the data source directory. This is a helpful task to create the schema in a form that DDLUtils can read. Once this is done, I usually make edits directly to that schema file. This is a database-independent way to keep the data definition up-to-date, and I think it’s easier to read and understand than SQL create statements.
When a developer checks in changes to this schema, other team members can get their local databases in sync with the latest version by running the next task: load-schema. DDLUtils is pretty good at doing non-destructive updates to the database too, but don’t worry too much about development data that’s in local databases. If there are changes to the database, there’s a chance that that data is wrong anyway. If you’d like to keep a set of data around for development that all developers can load easily, look at the next tasks:
<target
name="export-full-dataset"
description="creates dbunit dataset file for all tables based on
existing data.">
<dbunit
driver="${datasource.driverClassName}"
url="${datasource.url}"
userid="${datasource.username}"
password="${datasource.password}">
<export dest="${src.dir}/full_dataset.xml" />
</dbunit>
</target>
<target
name="clean-database"
description="clears all data from the database. ARE YOU SURE
YOU WANT TO DO THIS?">
<dbunit
driver="${datasource.driverClassName}"
url="${datasource.url}"
userid="${datasource.username}"
password="${datasource.password}">
<operation
type="DELETE_ALL"
src="${src.dir}/datasets/empty_dataset.xml" />
</dbunit>
</target>
<plugin>
The next task shows how to load data instead of exporting it. It comes with a little twist, though: I use a file that has rows for each table with no data in them, with a DELETE_ALL-type operation, and all the data is deleted. This is an easy utility task for cleaning out the database. Of course, you could adapt this task easily with a data set that actually has data so that you can share data with all the members of the team. Perhaps you could have a set of data which contains a lot of products and a test customer, making it easy to set up some shopping-cart tests. Maybe you’d like to share a lot of data to be used with performance tests. In any case, this approach is easier to maintain than a lot of SQL statements in a text file.
Better than having each team member have to remember to run `ant load-schema` every time the schema changes, or just every time they check out, is to have Maven run it for them. Here’s the relevant section of the data project’s pom.xml:
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution">
<phase<process-resources</phase<
<id>ant-data-tasks</id>
<configuration>
<tasks>
<property name="user.home" value="${user.home}" />
<ant antfile="${basedir}/build.xml" inheritRefs="
true">
<target name="load-schema"/>
</ant>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
This configures the Maven Ant run plug-in to run from build.xml a task called load-schema every time during the process-resources phase of the build. It also helps Ant by passing in the value of the user’s home directory, where the local repository is kept.
In the next installment, we'll examine the UI part of the project including building Flex from Maven through Ant and automatically running external tasks from Eclipse. You can always find the entire series here.







Facebook Application Development
Greetings once more..
Id like to note in relation to dbunit that if the deployed application is launched in the browser and a book is eventually reserved, running "mvn package" afterwards will cause TestBrowsing.setup() to fail...
This is due to the fact that there is an entry in the reservations table already, I believe. Dbunit tries to clear the table with CLEAN_INSERT, which seems to fail?! Therefore, I replaced line 36 in lcds.examples.bookie.entity.TestBrowsing:
DatabaseOperation.CLEAN_INSERT.execute(connection, searchableBooksDataset);
with
DatabaseOperation.REFRESH.execute(connection, searchableBooksDataset);
This does not try to clear the reservations table and allows passing the tests.
The other option in my hands was to always delete ALL rows from the reservations table MANUALLY before each project build!!! ugh..
;)
task called load-schema every time during the process-resources phase of the build. It also helps Ant by
Business management degree & doctorate degreepassing in the value of the user’s home directory, where the local repository is kept.
It comes with a little twist, though: I use a file that has rows for each table with no data in them, with a DELETE_ALL-type operation, and all the data is deleted. This is an easy utility task for cleaning out the database. Of course, you could adapt online phd degree this task easily with a data set that actually has data so that you can share data with all the members of the team. Perhaps you could have a set of data which contains a lot of products and a test customer, making it easy to set up some shopping-cart tests. Maybe online business school you’d like to share a lot of data to be used with performance tests. In any case, this approach is easier to maintain than a lot of SQL statements in a text file.
lot of data to be used with performance tests. In any case, this approach is easier to maintain than a lot earn diploma of SQL statements in a text file.