I was looking for a particular spring-web version in my local Maven repo and found quite a few and then went on to look for spring-core versions to find this:

118658 markus 20080602 ./spring-core/1.2.6/spring-core-1.2.6.jar
169450 markus 20081001 ./spring-core/2.0/spring-core-2.0.jar
172430 markus 20070606 ./spring-core/2.0.1/spring-core-2.0.1.jar
173719 markus 20070731 ./spring-core/2.0.2/spring-core-2.0.2.jar
178417 markus 20070606 ./spring-core/2.0.3/spring-core-2.0.3.jar
179193 markus 20080507 ./spring-core/2.0.4/spring-core-2.0.4.jar
180362 markus 20070607 ./spring-core/2.0.5/spring-core-2.0.5.jar
180002 markus 20080923 ./spring-core/2.0.6/spring-core-2.0.6.jar
182534 markus 20080110 ./spring-core/2.0.7/spring-core-2.0.7.jar
182184 markus 20100921 ./spring-core/2.0.8/spring-core-2.0.8.jar
270968 markus 20100303 ./spring-core/2.5/spring-core-2.5.jar
284876 markus 20080511 ./spring-core/2.5.3/spring-core-2.5.3.jar
285801 markus 20090829 ./spring-core/2.5.4/spring-core-2.5.4.jar
287235 markus 20081022 ./spring-core/2.5.5/spring-core-2.5.5.jar
285603 markus 20090629 ./spring-core/2.5.6.SEC01/spring-core-2.5.6.SEC01.jar
285491 markus 20090629 ./spring-core/2.5.6/spring-core-2.5.6.jar
359338 markus 20100119 ./spring-core/3.0.0.RELEASE/spring-core-3.0.0.RELEASE.jar
367170 markus 20100917 ./spring-core/3.0.4.RELEASE/spring-core-3.0.4.RELEASE.jar
382442 markus 20110524 ./spring-core/3.0.5.RELEASE/spring-core-3.0.5.RELEASE.jar
382184 markus 20140215 ./spring-core/3.0.6.RELEASE/spring-core-3.0.6.RELEASE.jar
383621 markus 20140927 ./spring-core/3.0.7.RELEASE/spring-core-3.0.7.RELEASE.jar
442400 markus 20140217 ./spring-core/3.1.0.RELEASE/spring-core-3.1.0.RELEASE.jar
449324 markus 20120825 ./spring-core/3.1.1.RELEASE/spring-core-3.1.1.RELEASE.jar
449649 markus 20140531 ./spring-core/3.1.2.RELEASE/spring-core-3.1.2.RELEASE.jar
879449 markus 20130314 ./spring-core/3.2.0.RELEASE/spring-core-3.2.0.RELEASE.jar
863642 markus 20130314 ./spring-core/3.2.1.RELEASE/spring-core-3.2.1.RELEASE.jar
866788 markus 20130526 ./spring-core/3.2.2.RELEASE/spring-core-3.2.2.RELEASE.jar
867800 markus 20140215 ./spring-core/3.2.3.RELEASE/spring-core-3.2.3.RELEASE.jar
872983 markus 20140217 ./spring-core/3.2.7.RELEASE/spring-core-3.2.7.RELEASE.jar
973502 markus 20140531 ./spring-core/4.0.3.RELEASE/spring-core-4.0.3.RELEASE.jar

Firstly I have this habit of copying the repo from one laptop to the next and sometimes between laptop and PCs, hence seven years of spring versions with gaps; Secondly, spring-core almost increased six times in in size between those versions.
It is also an indicator since when I have been using Spring with Maven : at least since mid 2007.

Martina and I were introducing Maven at our workplace at that time as part of a JPA / Struts2 project that was using Spring for IOC.

So on the same laptop I checked for the oldest jar:


498051 markus 20051123_052529 ./struts/struts/1.1/struts-1.1.jar
    40 markus 20060208_104252 ./opensymphony/xwork/1.1.1/xwork-1.1.1.jar.sha1

Hmm, 2005. Not sure what that means.

I wanted to know how easy it would be to get Spring-Boot auto-reconfiguration to work in OpenShift. It did not really work for me in Cloud Foundry without some massaging ( auto re-config blog ).

The proper way would be to extend https://github.com/spring-projects/spring-cloud/tree/master/spring-cloud-core for OpenShift Which is probably dead simple, too, but I wanted to do a quick 30 minute hack which become about a 90 minutes dirty hack.

In simple terms, the cartridge always sets -Dspring.profiles.active=cloud (unless this is overwritten by the app developer). And when it finds a ‘OPENSHIFT_MYSQL_DB_URL’ environment variable (which means the user added that service (cartridge) to the application, then the cartridge will add a the MariaDB (MySQL) information to ‘VCAP_SERVICES’ In addition I als set ‘VCAP_APPLICATION’ to some partially correct values, as well as VCAP_APP_HOST and VCAP_APP_PORT.

Then I deployed the jar generated from the unfamous-quotes cloud-foundry-autoreconfig-tests branch and it correctly picked up the MySQL DB and SUCCESS.

It was ridiculously easy to get that working in OpenShift. If I hadn’t put in a typo in one of my first attempts it would have been even easier.

What I did not mentioned in the last blog was that the version of the “unfamous quotes” code only works on Cloud Foundry if there is a data source supplied by Cloud Foundry. Otherwise you get:

org.springframework.cloud.CloudException: No unique service matching interface javax.sql.DataSource found. Expected 1, found 0

This happens due to the this code in DataSourceConfiguration:

return connectionFactory().dataSource();    

With the current version of the spring runner cartridge the same happens: You have to add a MariaDB or it wont work.

Since this was just a quick and dirty test, I did not add any other DB services. But I also would rather check out the spring-core-cloud and create an OpenShift Cloud Connector.

I started with the code from https://github.com/spring-guides/gs-accessing-data-jpa.git (complete). I then added a simple HTML/JS UI on top of the Restful API and added validation.

The way Spring Boot works in this set-up is that it automatically creates an in-memory H2 DB and auto-wires everything together. There is basically no code and it works fine and is simple enough. All in an executable Jar with an embedded Tomcat (~29M).

I uploaded that example to different Cloud PaaS providers as well as private PaaS running in a VM and it
either required no or very little effort to run it (except for one where it failed completely … see previous posts).

What surprised me was that Cloud Foundry does not seem to support auto-reconfig for a jar packaged Spring Boot application. When I added a MySQL service and happily expected it to magically work and instead Cloud Foundry continued to start with the H2 DB (relevant git commit).

I tried different set-ups, but in the end I had to add an additional Spring cloud configuration file:

public class DataSourceConfiguration {
    @Configuration()
    public static class CloudConfiguration extends AbstractCloudConfig {
        @Bean(destroyMethod = "close")
        public javax.sql.DataSource dataSource() {
            return connectionFactory().dataSource();
        }
    }
}

And it immediately picked up the MySQL DB Did not create tables, though for that I also had to set spring.jpa.hibernate.ddl-auto=update in the application.property file.

The problem with that approach is that it won’t work locally:

Caused by: org.springframework.cloud.CloudException: No suitable cloud connector found

My thought was that it might just work with using the cloud profile so I changed it

public class DataSourceConfiguration {
    @Configuration()
    @Profile({ "cloud" })
    public static class CloudConfiguration extends AbstractCloudConfig {
        @Bean(destroyMethod = "close")
        public javax.sql.DataSource dataSource() {
            return connectionFactory().dataSource();
        }
    }
}

But that profile is not set by Cloud Foundry. One option could be to set the AbstractCloudConfig profile as default and set a different (e.g. local) profile for local development (see DataSourceConfiguration commit)

This works for this project, but might not for others.

Another option could be to set the cloud profile only when deploying to Cloud Foundry via e.g. JAVA_OPTS (see older posts). Either way can be a awkward for anyone not knowing the chosen path.

I prefer the second option because it means that local development works as expected and the same code behaves exactly the same way in Cloud Foundry (ie using H2 instead of MySQL. (see DataSourceConfiguration commit for cloud profile)

And with a specific manifest.yml file this can be overwritten for Cloud Foundry (though I don’t like having this file as part of the code) so that the active Spring Profile is “cloud”. With this set-up the code uses H2 locally and will use the DB service provided by Cloud Foundry – in my case MySQL – when deployed to Cloud Foundry.