How to create and drop database in DB2 using maven script - database

I am trying to run maven script and drop and create the databases.
This is my xml
.....
<plugin>
<!-- Used to automatically drop (if any) and create a database prior
to running integration test cases. -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<!-- <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.22</version>
</dependency> -->
<dependency>
<groupId>db2.connector</groupId>
<artifactId>db2.connector</artifactId>
<version>10.5.0.1</version>
<scope>system</scope>
<systemPath>${basedir}/../data/target/db2jcc.jar</systemPath>
</dependency>
<dependency>
<groupId>db2.connector</groupId>
<artifactId>db2.connector4</artifactId>
<version>10.5.0.1</version>
<scope>system</scope>
<systemPath>${basedir}/../data/target/db2jcc4.jar</systemPath>
</dependency>
</dependencies>
<configuration>
<!-- common configuration shared by all executions -->
<driver>com.ibm.db2.jcc.DB2Driver</driver>
<username>db2inst1</username>
<password>password</password>
<url>jdbc:db2://192.168.0.81:50000/db</url>
<forceMojoExecution>true</forceMojoExecution>
</configuration>
<executions>
<execution>
<id>drop-db-before-test-if-any</id>
<phase>pre-integration-test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<autocommit>true</autocommit>
<sqlCommand>drop database db</sqlCommand>
<onError>continue</onError>
</configuration>
</execution>
<execution>
<id>create-db</id>
<phase>pre-integration-test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<autocommit>true</autocommit>
<sqlCommand>create database db</sqlCommand>
</configuration>
</execution>
<execution>
<id>create-schema</id>
<phase>pre-integration-test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<url>jdbc:db2://192.168.0.81:50000/sample</url>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>${basedir}/../data/src/main/resources/create_database_db2.sql</srcFile>
</srcFiles>
</configuration>
</execution>
</executions>
</plugin>
.....
The error I get is
[ERROR] com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-104,
SQLSTATE=42601, SQLERRMC=database;drop ;<program_or_package>, DRIVER=3.66.46
[INFO] 0 of 1 SQL statements executed successfully
Similar error for create db.
What am I doing wrong in this?

I'm not a Maven expert, but the issue you're running into is that you're trying to run DROP DATABASE as a SQL command, when it is a DB2 Command-Line processor command.
This thread might be of some help, it's about running DB2 CLP commands in Java.

As Bhamby said, you cannot execute a "create database", nor a "drop database" as a SQL command. That is the reason you are having those kind of errors.
Command script via exec-maven-plugin
What you can do is to execute a command from Maven, but before, you have to be sure that the DB2 environment is correctly loaded. You can use the exec-maven-plugin plugin, but instead of executing different commands to load the DB2 profile and then creating the database, what you can do is to write a script that will receive the database name as parameter, and the script will create the database. The problem here, is that you have to write one for Linux, and one for Windows. For example in linux:
create.sh
#!/bin/bash
. /home/db2inst1/sqllib/db2profile
db2 create db $1
The instance home directory here was: /home/db2inst1.
Also, you have to be sure, the user used to execute Maven has the necessary rights at the instance to create a new database. I mean, the user should be in the sysadm or sysctrl group: http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.admin.cmd.doc/doc/r0001941.html
Java
You cannot create the database via Java, because the DB2 API does not provide a Java API for this. Instead, you can create a C routine called from JNI and invoke it in Java. In this way, you can personalize the creation/dropping process from Java, and not from a script.

Related

Maven cxf plugin logging

I'm using the Apache cxf maven plugin (v3.3.0) to successfully to generate java wrappers.
However, the output from the maven build contains thousands of DEBUG logging lines from the wsdl2java which I am unable to remove. Is there an extraarg or other way to silence the process so I get just a success (or possibly failure) message?
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
<defaultOptions>
<autoNameResolution>true</autoNameResolution>
</defaultOptions>
<wsdlOptions>
<!--Some Web Service -->
<wsdlOption>
<wsdl>https://some/web/service.wsdl</wsdl>
<extraargs>
<extraarg>-client</extraarg>
<extraarg>-quiet</extraarg>
<extraarg>-p</extraarg>
<extraarg>com.foo.bar</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
It appears that under Java 9+ the plugin forces code generation in a forked JVM regardless of the default being documented as false and regardless of any explicit configuration of this option. The plugin execution doesn't see any logging configuration from the project. CXF is logging using java.util.logging and any log down to FINER severity gets printed to the console.
I solved this by providing an explicit path to a logging configuration file to the forked JVM using the plugin's additionalJvmArgs configuration option:
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf-plugin.version}</version>
<configuration>
<additionalJvmArgs>-Dlogback.configurationFile=${project.basedir}/src/test/resources/logback-codegen.xml</additionalJvmArgs>
</configuration>
</plugin>
The system property for Logback (as in my case) is logback.configurationFile. For Log4j that would be log4j.configurationFile.
In the logging configuration file the following loggers can be added (Logback):
<!-- entries below silence excessive logging from cxf-codegen-plugin -->
<logger name="org.apache.cxf" level="info"/>
<logger name="org.apache.velocity" level="info"/>
This way the plugin execution will still print to the console all warnings and errors, but all the repetitive debug information goes away. The drawback is that you need to have such a logging configuration file visible in each of your projects. But then, you probably should have one anyway. The same one as for (unit) tests can often be used.
Sorry for not getting into the root solutions, but adding this in my dependencies help:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<scope>provided</scope>
</dependency>
or put following in plugin execution helps too except for velocity logs
<additionalJvmArgs>
-Dorg.apache.cxf.Logger=null
</additionalJvmArgs>
Hope this would give a hints for someone to come out with a much proper solution.
Using maven-3.8.4 and cxf-codegen-plugin:3.5.1:wsdl2java, I've reduced log level with:
<configuration>
<additionalJvmArgs>-D.level=WARN</additionalJvmArgs>
</configuration>
More details here: Apache CXF

Using encrypted password in settings.xml for dockerfile-maven-plugin

We are using dockerfile-maven-plugin from spotify. The plugin configuration is below and also settings.xml snippet follows. Noticed that if we try to use encrypted password with master password configured in the settings-security.xml, dockerfile-maven-plugin fails. Question is whether dockerfile-maven-plugin allows us to use encrypted password or not.
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.6</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>host:port/${project.artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<EAR_FILE>${project.build.finalName}.ear</EAR_FILE>
</buildArgs>
<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
</configuration>
</plugin>
settings-security.xml
<settingsSecurity>
<master>{Ve/ckepqKaIHGVED4WvoUn3htWLfPef158/35o9gdcM=}</master>
</settingsSecurity>
settings.xml
<servers>
<server>
<id>host:port</id>
<username>zenDocker</username>
<password>{rdSNF21NPqMH70L7wKs1ZKg4nWF+8m+Hm3rFrpt/a+g=}</password>
</server>
</servers>
I had the same problem and I solved it by using this maven extension:
<extension>
<groupId>com.github.shyiko.servers-maven-extension</groupId>
<artifactId>servers-maven-extension</artifactId>
<version>1.3.0</version>
</extension>
Reference I used: https://apexplained.wordpress.com/2015/08/08/password-encryption-in-the-liquibase-maven-plugin/
My config results the following:
settings.xml
<server>
<id>hub.example.com</id>
<username>myUsername</username>
<password>{q6S7TmCyTP0H0q0IGOSsgnHSdbQlwXRcAF6h4Jvh/b0=}</password>
</server>
pom.xml
<build>
<extensions>
<extension>
<groupId>com.github.shyiko.servers-maven-extension</groupId>
<artifactId>servers-maven-extension</artifactId>
<version>1.3.0</version>
</extension>
</extensions>
<plugins>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${com.spotify.dockerfile-maven-plugin.version}</version>
<configuration>
<repository>hub.example.com/${project.artifactId}</repository>
<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
Quote from README.md (v1.4.3):
Since version 1.4.3, using an encrypted password in the Maven settings file is supported. For more information about encrypting server passwords in settings.xml, read the documentation here.
I came across the same problem/question. Based on code at https://github.com/spotify/dockerfile-maven/blob/master/plugin/src/main/java/com/spotify/plugin/dockerfile/MavenRegistryAuthSupplier.java#L50 and try-and-error exercises, password is expected to be in an open form
return RegistryAuth.builder()
.username(server.getUsername())
.password(server.getPassword())
.build();

Resolving Izpack artifacts using maven dependency

I have Izpack installer which packs a pre-configured server and installs in target directory. This server is around 500Mb. Currently I have checked in this src/main/resources folder of installer maven project.But having this big server in git is making the git pulls very slow. So i am planning to keep this server as maven artifact in nexus and add its dependency to installer maven project. This way i can create a maven profile to pull this server from nexus on demand. I am yet to figure out how to copy this dependency to staging folder using a maven plugin(any help would be greatly appreciated). My question here, is it a right approach? or is there any better way to do this. Thanks in advance.
You can use the maven dependency plugin to copy a dependeny to a specific folder.
You can use it to either copy all dependencies or even unpack those dependencies.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<outputDirectory>${izpack.staging}/content/ninjolibs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
This is what i did. I uploaded wso2.zip to nexus as zip artifact and configured pom.xml of my installer module to use this dependency.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-binaries</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wso2</groupId>
<artifactId>wso2is</artifactId>
<version>5.0.0</version>
<type>zip</type>
<overWrite>true</overWrite>
<outputDirectory>src/main/resources/wso2/binary</outputDirectory>
<destFileName>wso2is-5.0.0.zip</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

Maven Proguard processing a library jar that other applications will depend one

Here is what my build plug in stanza looks like:
<plugin>
<groupId>com.pyx4me</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<options>
<option>-dontshrink</option>
<option>-dontnote</option>
<option>-allowaccessmodification</option>
<option>-dontskipnonpubliclibraryclasses</option>
<option>-dontskipnonpubliclibraryclassmembers</option>
</options>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jsse.jar</lib>
</libs>
</configuration>
</plugin>
Here is what I get from execution of mvn clean package
[proguard] Error: You have to specify '-keep' options for the shrinking step.
How do I specify the keep options for a library where I just want obfuscation?
You must define with the -keep option the entry points of your application, because you can't obfuscate it. For example if your main class is obfuscated it will be renamed and you won't be able to launch it. The same for public interfaces of your APIs.

Best way to create / drop a database before / after integration testing on a Maven/Junit/DBUnit project?

I've seen some people use the maven-sql-plugin to do this. But it seems like a task that is better suited for DBUnit....perhaps at the beginning of an entire test suite.
What's the best practice here?
I use the Maven SQL Plugin
You're much better off using it and making sure that you create and populate before your tests and then drop after your tests. You'll also want to use create or replace, or drop if exists in your creation script (assuming your database supports it) in the event that a test fails and leaves the database in some inconsistent state.
It took some fiddling around, but I got it to drop, create, and create the schema for H2 and MySQL. Still need to finish it for Oracle and SQL*Server 2008. I tucked the exact DROP and CREATE commands into properties and in some cases (such as H2) needed to skip the create database altogether. Here is what it looks like:
<plugin>
<!-- Used to automatically drop (if any) and create a database prior to running integration test cases. -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<dependencies>
<dependency>
<!-- Adds the correct JDBC driver as a dependency of this plugin -->
<groupId>${database.groupId}</groupId>
<artifactId>${database.artifactId}</artifactId>
<version>${database.version}</version>
</dependency>
</dependencies>
<configuration>
<!-- common configuration shared by all executions -->
<driver>${database.class}</driver>
<username>${database.username}</username>
<password>${database.password}</password>
<url>${database.url}</url>
</configuration>
<executions>
<execution>
<!-- Start by dropping the database (we'll leave it intact when finished) -->
<id>drop-db</id>
<phase>pre-integration-test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<!-- Can't use regular URL in case database doesn't exist -->
<url>${database.url.alternate}</url>
<skip>${database.sqlDrop.skip}</skip>
<autocommit>true</autocommit>
<sqlCommand>${database.sqlDrop};</sqlCommand>
<onError>continue</onError>
</configuration>
</execution>
<execution>
<!-- then create a new database -->
<id>create-db</id>
<phase>pre-integration-test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<!-- Can't use regular URL in case database doesn't exist -->
<url>${database.url.alternate}</url>
<skip>${database.sqlCreate.skip}</skip>
<autocommit>true</autocommit>
<sqlCommand>${database.sqlCreate};</sqlCommand>
<onError>continue</onError>
</configuration>
</execution>
<execution>
<!-- and finally run the schema creation script we just made with the hibernate3-maven-plugin -->
<id>create-schema</id>
<phase>pre-integration-test</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<skip>${database.sqlSchema.skip}</skip>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>target/hibernate3/sql/create-${database.vendor}-schema.sql</srcFile>
</srcFiles>
<onError>continue</onError>
</configuration>
</execution>
</executions>
</plugin>

Resources