Try to use flyway for multiple DB instances - java

Running the Maven flyway-plugin
mvn flyway:migrate
with this configuration:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>4.0.3</version>
<configuration>
<driver>com.mysql.jdbc</driver>
<url>jdbc:mysql://localhost:3306/schema2?createDatabaseIfNotExist=true</url>
<user>root</user>
<password>root</password>
</configuration>
</plugin>
I try to create number of executions like in this solution:
How to use Flyway configuration to handle multiple databases
Start from one execution:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>4.0.3</version>
<executions>
<execution>
<id>migrate-database</id>
<phase>compile</phase>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<driver>com.mysql.jdbc</driver>
<url>jdbc:mysql://localhost:3306/schema2?createDatabaseIfNotExist=true</url>
<user>root</user>
<password>root</password>
</configuration>
</execution>
</executions>
</plugin>
See exception:
[ERROR] Failed to execute goal org.flywaydb:flyway-maven-plugin:4.0.3:migrate (default-cli) on project UrbanLife: org.flywaydb.core.api.FlywayException: Unable to connect to the database. Configure the url, user and password! -> [Help 1]
Looks like flyway can't see configuration inside
(Interesting that, in link, I mentioned before, it works)
Please help to create flyway multyDB integration via maven.

When you have multiple (or just one) <execution> in your maven plugin configuration and are attempting to run a specific execution from the command line you need to specify the execution by the execution id like so in your case
mvn flyway:migrate#migrate-database
see also: How to execute maven plugin execution directly from command line?
Lastly, if you want a specific execution to be the default, you can give it the execution id of default-cli as explained in these maven docs. Then you can simply run mvn flyway:migrate.

The FQN of the driver is incorrect, it should be com.mysql.jdbc.Driver or you could also simply remove it as it will be auto-detected from the URL.
You will also need to add the driver as dependency of your plugin by adding
<plugin>
...
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
</dependencies>
</plugin>

Related

Java: Can't find symbol: class name, when the class name in one of two packages with the same name [duplicate]

I use maven to build a multi module project. My module 2 depends on Module 1 src at compile scope and module 1 tests in test scope.
Module 2 -
<dependency>
<groupId>blah</groupId>
<artifactId>MODULE1</artifactId>
<version>blah</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
This works fine. Say my module 3 depends on Module1 src and tests at compile time.
Module 3 -
<dependency>
<groupId>blah</groupId>
<artifactId>MODULE1</artifactId>
<version>blah</version>
<classifier>tests</classifier>
<scope>compile</scope>
</dependency>
When I run mvn clean install, my build runs till module 3, fails at module 3 as it couldn't resolve the module 1 test dependency. Then I do a mvn install on module 3 alone, go back and run mvn install on my parent pom to make it build. How can I fix this?
I have a doubt about what you are trying to do but but I'll assume you want to reuse the tests that you have created for a project (module1) in another. As explained in the note at the bottom of the Guide to using attached tests:
Note that previous editions of this guide suggested to use <classifier>tests</classifier> instead of <type>test-jar</type>. While this currently works for some cases, it does not properly work during a reactor build of the test JAR module and any consumer if a lifecycle phase prior to install is invoked. In such a scenario, Maven will not resolve the test JAR from the output of the reactor build but from the local/remote repository. Apparently, the JAR from the repositories could be outdated or completely missing, causing a build failure (cf. MNG-2045).
So, first, to package up compiled tests in a JAR and deploy them for general reuse, configure the maven-jar-plugin as follows:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Then, install/deploy the test JAR artifact as usual (using mvn install or mvn deploy).
Finally, to use the test JAR, you should specify a dependency with a specified type of test-jar:
<project>
...
<dependencies>
<dependency>
<groupId>com.myco.app</groupId>
<artifactId>foo</artifactId>
<version>1.0-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
...
</project>
Regarding to my comment to Pascals question i think i have found a stuitable answer :
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
<phase>test-compile</phase>
</execution>
</executions>
<configuration>
<outputDirectory>${basedir}\target</outputDirectory>
</configuration>
</plugin>
</plugins>
The main difference here as you see here is the <phase> tag.
I will create the test-jar and it will be available in the compile phase of the tests and not only after the package phase.
Works for me.

Add jvm options to maven plugin execution

Is it possible to force any maven plugin to execute with VM arguments when I do mvn clean install?
More context
I have an old project that I try to mirgate to java 11. During this migration I had trouble with wadl-client-plugin and JAXB showing this error.
schema_reference: Failed to read schema document '...', because 'file' access is not allowed due to restriction set by the accessExternalSchema property.
When I run it like mvn clean install -Djavax.xml.accessExternalSchema=all it works. I need to include somehow -Djavax.xml.accessExternalSchema=all to the plugin execution when I run mvn clean install. I've checked wadl-client-plugin's docs and don't see anything about it. Is it possible to do it somehow in general way? Configuring local JVM is not an option neither as I cannot do it at all machines.
I finally found an answer here
properties-maven-plugin inside my pom did the trick.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>set-additional-system-properties</id>
<goals>
<goal>set-system-properties</goal>
</goals>
</execution>
</executions>
<configuration>
<properties>
<property>
<name>javax.xml.accessExternalSchema</name>
<value>all</value>
</property>
</properties>
<outputFile/>
</configuration>
</plugin>

Local non maven jar is searching on maven server. Why?

[ERROR] Failed to execute goal on project portal: Could not resolve dependencies for project com.learning:portal:war:1.0.0-SNAPSHOT: Could not find artifact com.myapp.Local-2017:jar:1.0 in central (https://repo.maven.apache.org/maven2)
In pom.xml:
<dependency>
<groupId>com.myapp.Local</groupId>
<artifactId>Local-2017</artifactId>
<version>1.0</version>
</dependency>
Plugins:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<phase>clean</phase>
<configuration>
<repositoryLayout>default</repositoryLayout>
<groupId>com.myapp.Local</groupId>
<artifactId>Local-2017</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<file>${basedir}/lib/Local.jar</file>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
You declared a Maven dependency
<dependency>
<groupId>com.myapp.Local</groupId>
<artifactId>Local-2017</artifactId>
<version>1.0</version>
</dependency>
If Maven does not find it in your local repository, it will try to download it from outside. If you do not have a settings.xml it will try MavenCentral.
I suspect that part of the problem is that you have put the execution of "maven-install-plugin" into the "clean" phase. According to the Maven 3.5 Documentation, the "clean" phase is part of the "clean" life-cycle; i.e. gets run when you run "mvn clean".
I think it should be in the "default" lifecycle, probably the "validate" or "initialize" phase. Note that dependency resolution typically occurs in a later phase. It happens in the first phase that uses a plugin that requires dependency resolution as a prerequisite. Put the "install-file" goal into an earlier phase in the lifecycle.

Running embedded H2 database with mvn jetty:run

I've been trying to figure out how to run an embedded database through a profile and be able to run REST calls through postman.
This is what I have so far:
<profile>
<id>developRest</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
<configuration>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:mem:test</url>
<username>sa</username>
<password>sa</password>
</configuration>
<executions>
<execution>
<id>my-execution</id>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>src/test/resources/table-ddl.sql</srcFile>
<srcFile>src/test/resources/insert-into-table.sql</srcFile>
</srcFiles>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
<webApp>
<descriptor>src/main/webapp/WEB-INF/jetty.xml</descriptor>
</webApp>
<stopKey></stopKey>
<stopPort></stopPort>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
</profile>
I've played around with phases but nothing really seems to stick. When I run this with mvn sql:execute#my-execution jetty:run, the servlet runs but once I call a rest method I get
Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (my-execution) on project myProject: The parameters 'driver', 'url' for goal org.codehaus.mojo:sql-maven-plugin:1.5:execute are missing or invalid
What am I missing that will get the driver and url to be valid? Thanks for your help.
Update: Used mvn -PdevelopRest sql:execute#my-execution jetty:run to get rid of the driver and url error but still stuck with:
### Error querying database. Cause: org.h2.jdbc.JdbcSQLException: Table "myTable" not found; SQL statement:
When calling a GET from postman. Any Thoughts?
I find it hard to believe that you get a Maven error when you call a REST method (Failed to execute goal ...).
That aside, I think your real problem is this: you are using H2 as an in-memory database, that means that it's available as long as your application runs. When your application goes away, so does your database.
In the context of Maven, where you have multiple plugins executing, the database does not outlive the execution of a single plugin. Your my-execution instantiates an in-memory database, which then goes away. The jetty-maven-plugin creates its own in-memory database, which then does not have any of the DDL/SQL that went into the previous one.
There is probably a number of ways to fix this, like these:
Don't use an in-memory database, rather have H2 write out files, e.g. jdbc:h2:/data/test, or, since you're using Maven: jdbc:h2:${project.build.directory}/data/test
Don't initialize the database using the sql-maven-plugin, but directly inside the application. You could do that:
With some custom code, that you only put on the test classpath
By adding the DDL/SQL to the connection string of the application ("Execute SQL on Connection"), like so:
jdbc:h2:mem:test;INIT=runscript from '~/table-ddl.sql'\\;runscript from '~/insert-into-table.sql'";
H2 is an awesome database. Good luck!

maven plugin run only if user preference

Is there a generic way to do this for any maven plugin - run based on user preference/ disable it based on a property file?
Have a properly working maven plugin using com.mysema.querydsl, now want to change is so it only runs if a particular flag/ command line options is provided.
<plugin>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>${querydsl-maven-plugin.version}</version>
//executions
<configuration>
<jdbcDriver>com.mysql.jdbc.Driver</jdbcDriver>
<jdbcUrl>jdbc:mysql://myurlk:port/db</jdbcUrl>
<jdbcUser>id1</jdbcUser>
<jdbcPassword>ccc</jdbcPassword>
<packageName>com.sample</packageName>
<targetFolder>${project.basedir}/src/main/java</targetFolder>
<schemaPattern>APP</schemaPattern>
//goal prefix here?
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
</dependency>
</dependencies>
</plugin>
Tried to add
<executions>
<execution>
<id>execution1</id>
<phase>test1</phase>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
and a goal prefix
<goalPrefix>mysema1</goalPrefix>
But not working. Want a way so this plugin is not run when we do a default
mvn clean install
But need to add another flag to make it run?
Using Apache Maven 3.0.4
Did you try to put the plugin execution into a Maven profile? There are several triggers to enable a profile for a build (e.g. OS, Java version, property value or the profile id itself on the command line).
See http://maven.apache.org/guides/introduction/introduction-to-profiles.html for more details.
Define a profile, add the plugin definition into the profile and add a property trigger for the profile like this:
<project>
...
<profiles>
<profile>
<id>profile-id</id>
<activation>
<property>
<name>myProperty</name>
</property>
</activation>
<build>
<plugins>
<plugin>
...
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
When you build yout project with mvn clean install the plugin will not be executed, when you build your project with mvn clean install -DmyProperty or mvn clean install -Pprofile-id your plugin will be executed. In the second case the property activation trigger for the profile is obsolete.

Categories