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.

I still have not had time to Linux on my Dell XPS 15 laptop and still have to suffer from Windows oddness that I do not know.
It does not help that this is the first time that I use Windows 8.1 and some things aare unfamiliar and to me very unintuitive. Under Linux I know where to look. Under Windows more than once in the last month did I have to resort to a reboot because things just stopped working or the machine went into slow motion mode and did not recover otherwise.

Yesterday just before going home I wanted to log back on to the the corporate WLAN “WLAN-One”. Just before I was connected, but I shut-down already and when powering on the machine hung after the Windows log-in. Several minutes passed and at some point it logged my into my Windows profile.

I could not log on to WLAN-One though. So tried corporate WLAN-Two. Nope.
Reboot. Nope neither work. Tried tethering to my tablet’s WLAN-tab. Nope.
Shutdown. Waiting. Start up. Nope.
Removed all connections (“forget”).Nope, none of the WLANs work.

Then I noticed that stupid windows remembered the wrong details. When connecting to WLAN-Two or WLAN-tab, ipconfig /all still showed connection information (IP, DNS, Gateway) for WLAN-One. These details always stayed the same once connected to any of the three.

Played with netsh with lots of delete/remove command. Rebooted. Still the same.
Tried for a good part of an hour to no avail. Search the web, checked out help information nothing helped.

Decided on a whim to restart the DHCP Clien service in the “services.msc” console.

Fixed !

Stupid Windows.

I sometimes have similar pains with Linux, but I know where to look and what do fix because it easy to find once you understand the concept.

I recently helped a Mac owner to resolve custom DNS issues, which wasn’t as easy since I am not a Mac user.

Moral of my story:

  • Even though computer usability came very far in the last decade(s) I and others are still hitting similar problems as 30 years ago.
  • Generally wordprocessing, Visio, PowerPoint are still tedious to use
  • Rebooting (or restarting things) solves most issues

Quite a few times I am having problems connecting to existing WiFi connections on my Dell XPS15 with Windows 8.1. Even though other devices can connect to the same WiFi switching between them does not work (‘limited connectivity’ aka no IP connectivity).
Even though rebooting did not help, restarting the DHCP client service did resolve it.

preparation

Started by making sure that the latest version still works.

I already confirmed with Active State that you cannot upload a JAR directly, but have to unpack it so:

from the working dir (same level as pom.xml)
cd ./unpacked/; unzip ../target/unfamous-quotes-0.0.1-SNAPSHOT.jar; ls -al; cd ..
stackato push –path ./unpacked/

But the application starts up on port 8080 which is not the port stackato wants it to run at and then it is killed and restarted and ..
application.properties still has an entry about the server.port which I commented out and retried. But the server still started on
port 8080. So I made sure that the application.properties file was really updated which it was.

In between tries I always removed application including the route with

stackato delete unfamous-quotes

No luck. nothing helped.
I don’t understand though since I have an example that works and this app worked fine before I did some static file changes.

No matter what I check or do stackato is not able to assign the right port and the server runs on 8080 until it is killed of.
Of course I could set the port like for my simple server test but that defeats the purpose.

Besides, the exact same JAR works on Pivotal’s Cloud Foundation free tier run.pivotal.io with a simple push.

cf push unfamous-quotes -p ./target/unfamous-quotes-0.0.1-SNAPSHOT.jar

Next I tried another trick that I already learned in my experiments. I upload the jar with Eclipse (STS)
Or you can also push with CF, but then I would have to log out of run.pivotal.io – which I am using in parallel –
and into stackato, which also works. But unlike the stackato CLI the cf CLI does not allow multiple targets
and swithcing between them. So Eclispe it is.
The push with Eclipse (or cf) will fail, too, but all it requires is a start of the app and the same jar works in stackato.

Except that this does not resolve anything, the server still tstats on 127.0.0.0

Setting the JAVA_OPTS environment variable has the same escaping problems as before, too.

At this stage I am ready for one of my once in a month stress-release cigarettes.
The stackato web UI does not do anything to calm me down, either. e.g. the page refresh is annoying.

Even cf set-env did not work I assume there is an incompatibility with the build back

since the logs show this, which neither seems to work nor does it contain any of my environment variables:

stackato[dea_ng.0]: Launching web process: $PWD/.java-buildpack/open_jdk/bin/java -cp $PWD/.:$PWD/.java-buildpack/spring_auto_reconfiguration/spring_auto_reconfiguration-0.8.9.jar -Djava.io.tmpdir=$TMPDIR -XX:MaxPermSize=64M -XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk/bin/killjava.sh -XX:PermSize=64M -Xms382293K -Xmx382293K -Xss995K org.springframework.boot.loader.JarLauncher --server.port=$PORT

And I give up for now.