Liquibase loadData changeset ignores context - spring

I have a jhipster project, with Java, Spring and Liquibase as always. I want to load mock users on "dev" mode only, but when deploying to Heroku using the "prod" profile, they are ALSO loaded. It's like the context is ignored completely by liquibase. What am I doing wrong here?
The application-prod.yml file has a liquibase context set to "prod"
spring:
liquibase:
contexts: prod
and the application-dev.yml is setting liquibase context to "dev":
spring:
liquibase:
contexts: dev
I have some mock user data that I want to load only on dev (when running on localhost), and the liquibase changeset looks like this:
<changeSet author="me" id="mock-data-1" context="dev" >
<loadData encoding="UTF-8"
file="config/liquibase/mock_users.csv"
separator=";"
tableName="jhi_user">
<column name="activated" type="boolean"/>
<column name="created_date" type="timestamp"/>
</loadData>
...
</changeSet>
All other changesets have no context applied.
(Probably not relevant but) my mock_users.csv looks like this:
id;login;password_hash;first_name;last_name;email;image_url;activated;lang_key;created_by;last_modified_by;created_date;team_id
5;user1;$2a$10$VEjxo0jq2YG9Rbk2HmX9S.k1uZBGYUHdUcid3g/vfiEl7lwWgOH/K;;;user1#localhost.com;;true;sv;system;system;2019-12-03T09:21:06Z;1
Here is my Procfile for Heroku deployment:
web: java $JAVA_OPTS -jar target/*.war --spring.profiles.active=prod,heroku --server.port=$PORT
release: cp -R src/main/resources/config config && ./mvnw liquibase:update -Pheroku
When deploying to Heroku however the logs say thay no context is set at all:
Liquibase settings:
...
2019-12-03T13:17:08.821255+00:00 app[release.7646]: [INFO] context(s): null
...
And the entire changeLog is executed, I can see that in the Heroku logs too.
How do I make sure the liquibase contexts from my application-prod.yml file are used correctly?
EDIT* I can make heroku run liquibase with prod context by editing the pom file, under the "heroku" profile, "liquibase maven plugin" setting the "contexts" tag:
<profile>
<id>heroku</id>
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<configuration combine.self="override">
<changeLogFile>src/main/resources/config/liquibase/master.xml</changeLogFile>
<diffChangeLogFile>src/main/resources/config/liquibase/changelog/${maven.build.timestamp}_changelog.xml</diffChangeLogFile>
<driver></driver>
<url>${env.JDBC_DATABASE_URL}</url>
<defaultSchemaName></defaultSchemaName>
<username>${env.JDBC_DATABASE_USERNAME}</username>
<password>${env.JDBC_DATABASE_PASSWORD}</password>
<referenceUrl>hibernate:spring:se.axesslab.respekttrappan.domain?dialect=org.hibernate.dialect.PostgreSQL82Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy</referenceUrl>
<verbose>true</verbose>
<contexts>prod</contexts>
<logging>debug</logging>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
</configuration>
</plugin>
But should this really be required? Then what's the point of having the application-*.yml files hold different liquibase contexts?

The execution of Liquibase is triggered from within the Maven plugin, ./mvnw liquibase:update -Pheroku. The maven plugin doesn't know about the Liquibase context you set in Spring's property file.
Like you figured out yourself, you have to either set the context in the pom.xml or let Spring execute Liquibase.

Related

maven error "Property ${samedir} has not been set"

How to fix the maven checkstyle plugin error
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.1.2:check (validate) on project yourproject:
Failed during checkstyle execution:
Failed during checkstyle configuration: unable to parse configuration stream:
com.puppycrawl.tools.checkstyle.api.CheckstyleException:
Property ${samedir} has not been set -> [Help 1]
${samedir} is a property working well with eclipse plugin and is required to get related files mentioned in the checkstyle configuration working well with eclipse IDE. So either I need a consistent replacement, or I can tell maven to define the property
Any ideas how to fix this issue?
You will have to set these values via the plugin configuration in your pom.
Example configuration of pom.xml if you have a directory named checks in your project root:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<configLocation>${basedir}/checks/checkstyle.xml</configLocation>
<propertiesLocation>${basedir}/checks/checkstyle_maven.properties</propertiesLocation>
</configuration>
</plugin>
And the checkstyle_maven.properties contents:
samedir=checks
As an alternative to the <propertiesLocation> you can also use the following, in which case you don't need the .properties file:
<propertyExpansion>samedir=${basedir}/checks</propertyExpansion>
This will make sure any configuration in checkstyle.xml will work like this:
<module name="Checker">
<module name="SuppressionFilter">
<property name="file" value="${samedir}/suppress.xml"/>
</module>
</module>
See for reference:
Using ${samedir} in Checkstyle-plugins for Gradle and Eclipse
http://rolf-engelhard.de/2011/04/using-the-same-suppression-filter-for-checkstyle-in-eclipse-and-maven/

Websphere 9 maven remote deployment

My springboot application builds into a WAR file (using Jenkins). I want to automate the remote deployment to Websphere 9.
I have read around and it seems there is no maven plugin for deployment to websphere 9 but ant support is pretty good. So, I'm using maven ant plugin to help running those ant tasks. I started with attempt to list the applications installed, just to see if it works. However I'm running into an exception related to localization:
[ERROR] C:\DEV\ant-was-deploy.xml:81:
java.util.MissingResourceException: Can't find bundle for base name
com.ibm.ws.profile.resourcebundle.WSProfileResourceBundle, locale
en_US
My ant-was-deploy.xml is referenced from pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>id123</id>
<phase>clean</phase>
<configuration>
<locales>es</locales>
<target>
<ant antfile="${basedir}/ant-was-deploy.xml">
<target name="listApps"/>
</ant>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
ant-was-deploy.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project name="websphere" default="listApps" basedir="." >
<target name="listApps" >
<taskdef name="wsListApps" classname="com.ibm.websphere.ant.tasks.ListApplications" classpath="${wasHome.dir}/plugins/com.ibm.ws.runtime.jar" />
<wsListApps
profileName="AppServ01"
wasHome="C:\\opt\\IBM\\WebSphere\\AppServer"
/>
</target>
</project>
I think the error comes from com.ibm.ws.runtime.jar. Inside it has WSProfileResourceBundle.class and WSProfileResourceBundle_en.class but not WSProfileResourceBundle_en_US.class (name is just an assumption - I have copied the bundle with this name inside the jar but it didn't work).
I also tried to set the locale for the entire plugin but it seems that localization for this plugin is not implemented properly (no impact in my case - I set the locale to 'es' but still got the error for en_US).
I also tried to pass system parameters to maven command: mvn clean -Duser.language=fr -Duser.country=FR
It didn't work either.
So, my question is if there is a way to change the locale before the ant script? If I can set it to 'en' probably it will find the right resource bundle.
I'm fairly new to Websphere, if there is another solution to automate the remote deployment to websphere 9 I would be happy to hear it. I would rather not use scripts on target server or Jenkins plugin but if there is no other way ...
I just had the same issue. In my case, i was using an AppServer name (AppSrv1 instead of AppSrv01) that did not exist anymore, in my maven settings.xml.
The right server name solved the issue.

Why not to use / as a context path in maven tomcat?

I'm using maven tomcat plugin to deploy an app. It does deploy in root context if I set path to <path>/<path> but I want to know if it causes any problems because the docs explicitly says "Do not use /".
Related question: How to set context path to root(“/”) in Tomcat 7.0 when using Maven
Why not to use / as path in maven tomcat?
The JavaDoc pointing out to "Do not use /" was introduced in this commit:
(MTOMCAT-102) Add a mojo to build a standalone jar to run a web application: use path field to store webapp to have a more nice name than projet.build.finalName
When scrolling down the commit you see that the path property value is used to create a JarArchiveEntry:
os.putArchiveEntry( new JarArchiveEntry( path + ".war" ) );
which for configured <path>/<path> would translate to a file name of "/.war" looking kind of invalid. On the other this would possibly yield to ".war" file name when extracted.
Today for version 2.2 this piece of code looks like this changed for bug MTOMCAT-103:
os.putArchiveEntry(
new JarArchiveEntry(
StringUtils.removeStart( path, "/" ) + ".war"
)
);
which for configured <path>/<path> would translate to ".war" as file name looking way more legal but still not really desirable imho.
As the Tomcat 7 Documentation states the base file name for the empty context path
(aka "/") should be ROOT your best bet is to choose <path>ROOT<path> to achieve the desired result.
Edit:
For reproducing this, I checked out tomcat-maven-plugin.git and used their integration test. I had some truble to get a functional build at all, bit after removing some stuff from their server.xml and changing tomcat7-maven-plugin version to 2.1 it worked:
This is the diff applyied to their integration test app:
diff --git a/tomcat7-maven-plugin/src/it/simple-war-exec-project/pom.xml b/tomcat7-maven-plugin/src/it/simple-war-exec-project/pom.xml
index 8ce51b7..e00f0ea 100644
--- a/tomcat7-maven-plugin/src/it/simple-war-exec-project/pom.xml
+++ b/tomcat7-maven-plugin/src/it/simple-war-exec-project/pom.xml
## -42,7 +42,7 ##
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
- <version>#pom.version#</version>
+ <version>2.1</version>
</plugin>
</plugins>
</pluginManagement>
## -65,7 +65,7 ##
</goals>
<phase>package</phase>
<configuration>
- <path>foo</path>
+ <path>ROOT</path>
<serverXml>src/main/tomcatconf/server.xml</serverXml>
</configuration>
</execution>
diff --git a/tomcat7-maven-plugin/src/it/simple-war-exec-project/src/main/tomcatconf/server.xml b/tomcat7-maven-plugin/src/it/simple-war-exec-project/src/main/tomcatconf/server.xml
index 76ab562..de086fc 100644
--- a/tomcat7-maven-plugin/src/it/simple-war-exec-project/src/main/tomcatconf/server.xml
+++ b/tomcat7-maven-plugin/src/it/simple-war-exec-project/src/main/tomcatconf/server.xml
## -19,14 +19,7 ##
<Server port="8010" shutdown="SHUTDOWN">
- <GlobalNamingResources>
- <!-- Used by Manager webapp -->
- <Resource name="UserDatabase" auth="Container"
- type="org.apache.catalina.UserDatabase"
- description="User database that can be updated and saved"
- factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
- pathname="conf/tomcat-users.xml" />
- </GlobalNamingResources>
+
<Service name="Catalina">
<Connector port="8080" keepAliveTimeout="1800000" maxKeepAliveRequests="30000" maxThreads="300" />
## -34,8 +27,6 ##
<Engine name="Catalina" defaultHost="localhost">
<Valve className="org.apache.catalina.valves.AccessLogValve"
resolveHosts="false" pattern="%t-ip:%a-protocol:%H-localPort:%p-path:%U-time:%D ms"/>
- <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
- resourceName="UserDatabase" />
<Host name="localhost" appBase="webapps" />
</Engine>
Then from within the folder /tomcat-maven-plugin/tomcat7-maven-plugin/src/it/simple-war-exec-project I did:
$ mvn clean package
...
[INFO] BUILD SUCCESS
...
$ cd target/
$ java -jar simple-war-exec-project-1.0-SNAPSHOT-war-exec.jar
...
INFORMATION: Deploying web application archive C:\Temp\tomcat-maven-plugin\tomcat7-maven-plugin\src\it\simple-war-exec-project\target\.extract\webapps\ROOT.war
...
And the result:

Hibernate hbm2ddl schema creation and Maven tests

I try to use the following Hibernate property to create the database schema.
<property name="hibernate.hbm2ddl.auto" value="create"/>
This is a Maven Java EE (Hibernate/Spring) project that consists of Maven unit tests which validates the database schema at the beginning. That means database schema is validated (and thus deployment fails) before it is created.
How can I overcome this issue?
Not sure to understand what you want to do, but if your DDL is generated before the test phase (and it should be the case if you do this at process-classes phase), it should exist when your tests are running.
<execution>
<phase>process-classes</phase>
<goals>
<goal>hbm2ddl</goal>
</goals>
</execution>

Jetty Maven Plugin is ignoring custom webdefault.xml

I'm trying to get around the common issue of Jetty locking static files on Windows with the technique of setting useFileMappedBuffer to false in webdefault.xml. Unfortunately, every time Jetty is not picking up my customized webdefault.xml.
I'm using Apache Maven 3.0.2. I've tried using the maven-jetty-plugin (v6.1.26) and jetty-maven-plugin (v8.0.0.M2) but with no difference. I've tried running clean and rebuilding as well before running Jetty.
I've verified each time that my webdefault.xml was taken from the same version as the plugin and has the correct settings, namely, only changing this setting from true to false:
...
<init-param>
<param-name>useFileMappedBuffer</param-name>
<param-value>false</param-value>
</init-param>
...
And here's what my pom.xml Jetty plugin section looks like:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<configuration>
<contextPath>/</contextPath>
<webDefaultXml>src/main/resources/webdefault.xml</webDefaultXml>
</configuration>
</plugin>
I've also tried altering the path to my file:
<webDefaultXml>${basedir}/src/main/resources/webdefault.xml</webDefaultXml>
Everywhere I've seen this exact solution and it sounds like it is working for others (although I found one instance where someone had my issue). The startup for jetty has this in the output:
> mvn jetty:run
...
[INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
[INFO] Web overrides = none
...
This further makes me think it isn't being applied. All the other paths are correct in the output.
My most direct issue that I'm seeing while Jetty is running is that whenever I edit a static file (JavaScript, CSS, etc.) with IntelliJ IDEA 10, I get this error message:
Cannot save file:
D:\...\... (The requested operation cannot be performed on a file with a user-mapped section open)
After I stop Jetty then it saves just fine. This happens every time.
Any ideas what I could be doing wrong? Thanks in advance.
I found an entirely different doc for the newer Jetty plugin jetty-maven-plugin (v8.0.0.M2) and it looks like the configuration name has changed:
http://wiki.eclipse.org/Jetty/Reference/webdefault.xml#Using_the_Jetty_Maven_Plugin
<project>
...
<plugins>
<plugin>
...
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<webAppConfig>
...
<defaultsDescriptor>/my/path/to/webdefault.xml</defaultsDescriptor>
</webAppConfig>
</configuration>
</plugin>
...
</plugins>
...
</project>
This now seems to work for the newer plugin. I'm still unsure why the v6 plugin does not pick up the customized config.
The only solution I found that worked with maven-jetty-plugin 6.1.24 was this:
http://false.ekta.is/2010/12/jettyrun-maven-plugin-file-locking-on-windows-a-better-way/
The Jetty documentation outlines three ways to do it (as of Jetty 9):
https://www.eclipse.org/jetty/documentation/current/troubleshooting-locked-files-on-windows.html
I successfully used the init-param method in Maven:
<!-- Running an embedded server for testing/development -->
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.9.v20180320</version>
<configuration>
<webApp>
<_initParams>
<org.eclipse.jetty.servlet.Default.useFileMappedBuffer>false</org.eclipse.jetty.servlet.Default.useFileMappedBuffer>
</_initParams>
</webApp>
</configuration>
</plugin>

Resources