• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Jeanne Boyarsky
  • Liutauras Vilda
Sheriffs:
  • Rob Spoor
  • Bear Bibeault
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:
  • Frits Walraven
  • Himai Minh

Platform independent way of creating a new DB with maven

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi there,

This is my first post, so, howdy fellow greenhorns! :-)

Now, what I am trying to achieve may seem a bit convoluted and if I am going about this the wrong way - please let me know, I am happy to change the approach.

I have a maven-built webapp (well, it's not quite there yet). I am trying to integrate a creation of a new DB instance into the build itself, but I don't want to bind it to any particular phase (as in, maven lifecycle phase), because it is only intended to be run when the developer wants to get rid of an existing DB and create a new one (not too often, hopefully), on their own local environment. So, it's a slightly different requirement to the very common one, when the new (possibly embedded) database is built and populated before unit/integration testing and then subsequently dropped.

The reason I am trying to do it with maven is to be as platform independend as possible. If I put the SQL into a bash script, some of my teammates (alas, most of them) won't benefit from it much.

Now, I do know there is an sql maven plugin, and I got it working easily, by simply binding it to one of the phases (initialize).

Ok, so the questions are:

- Am I doing it wrong? Are there any "best practices" that apply to this scenario? Am I missing something?
- How can I execute a maven "execution" outside of "phase" scope?

As you can see, I am a maven newbie (started yesterday!), so I may be talking nonsense. Feel free to point that out :-) It may be because I am used to an obvious ant-like flow control in building scripts, and the declarative/IoC style of maven is not quite clear to me yet.

Some resources on similar topics I found:
http://stackoverflow.com/questions/22222808/automatically-creation-of-test-databases-using-maven
http://stackoverflow.com/questions/3166538/how-to-execute-maven-plugin-execution-directly-from-command-line

Thanks.
Michal
 
Michal Aleksander
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Answering myself.

What I ended up doing is actually pretty simple.

I declared a property db.skip.create and set it to false in properties section of pom.xml and added
<skip>${db.skip.create} </skip> in the execution section of the mysql maven plugin. The execution is still tied to the initialization phase but will not be invoked, unless db.skip.create is set to false. So, to create the db I use:

mvn initialize -Ddb.skip.create=false;

This is platform independend, external tools don't have to be run and it is driven by maven, so it solves my problem.

I will still leave this unsolved for a day or two, in case someone comes up with a neater solution.

Cheers,
Michal
 
author
Posts: 5856
7
Android Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
On the Maven command line, you can provide two types of goals:

1) A Maven lifecycle phase, such as "compile", "package", "deploy"

2) A Maven plugin goal, such as "dependency:tree", "surefire:test" and "sql:execute"

I think what you are looking for is the second type of goal. For this, declare the sql plugin, configure it, but don't assign it to any lifecycle phase. Then when someone wants to generate a database, they can add ""sql:execute" to the Maven arguments.

Of course the solution you mentioned also works - many plugin goals offer options to ignore the execution of the option based on a property setting. I use this capability quite often to prevent certain plugins from running on a developer's PC, but to ensure that the plugin runs in the build environment.
 
Michal Aleksander
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Peter. I would much prefer the approach of leaving the plugin's goal unassigned and simply calling if from the command line, but the issue here is that I have multiple executions for the same "execute" goal (it's the only goal in this plugin) each with different configuration: One for building a DB, one for dropping it and one for populating it with data. The nature of this build forces me to leave the phases separate. I suppose what I am looking for is a way to call a particular execution, something like: "mvn sql:execute:<execution_id> but I have not found a way of doing that.
 
Saloon Keeper
Posts: 23729
161
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You would typically do something like the following. This particular example intends to construct a webapp the hard way (instead of using the "package" goal) and run the function to create its database:



This would be your "sql:execute:initdb1".

No warranties express or implied. Variable settings on the Maven command line carry restrictions that may keep this from working and you need a POM that's up to work with it that way. But that's the general pattern for such things, where possible.
 
Michal Aleksander
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Tim, I presume that in your example SQLCODE is an arbitrary variable which is supposed to hold the filename that will then be referenced from within the execution of an "execute" goal of the plugin, right?
 
Tim Holloway
Saloon Keeper
Posts: 23729
161
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yep. Or whatever works best for you.

Note that for filenames, Maven can be a bit obstinate, however. Because it expects projects to be instantly transportable to far-off locations with completely different setups, it has limits on what you can do with variable filenames. This isn't database-specific. It's a general Maven restriction.
 
Rancher
Posts: 2759
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Personally, and YMMV and all that, I try to stay away from having maven do anything that cannot be bound to a phase. The beauty of maven lies in developers following convention. Basically, any new developer should be able to run mvn clean install and get up and running. If your standard build instructions are

mvn clean install db:setup scratch:behindear war:deploy jump: ononefoot

You'll have to make sure every developer runs that exactly. And eventually, everyone will forget why jump: ononefoot is there, but everyone will use it, because "hey.. that's what we've been told"


If your tests require a clean database, then your script for cleaning out a test database should be run everytime. Yes, this will make the build slow. I am of the opinion, that it's better to add arguments to the command line to make the build take shortcuts rather than make the shortcut the standard. So, for example

mvn clean install should do the full setup
mvn clean install -DskipDBDeployment should do the full setup without database demployment

Again, YMMV. Personally, I dislike command line arguments in build scripts. You might as well ditch Maven and go Ant. It's easier to do this in Ant.
 
Michal Aleksander
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That is a fair point, I will adjust the logic of how my "db.skip.*" properties are handled.

And yeah, I am coming from ant background, so for me most of the things are still easier to achieve with ant than with maven. But as you said, the beauty is there and I am slowly learning to see it.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic