
I did the customHTTPcodes sample project last year before spring 4 was released. That project included two branches
both based on Spring 3.2 and Java 7. After Java 8 was released I found time to update not only to Spring 4.0.3 but also to latest java major version 8. This article includes the update steps with some detailed hands on experiences. Result of this effort is sample source code based on Java 8 and Spring 4.0.3 apllied to the existing branches:
.
There are differences how to migrate to Java 8 on Xubuntu and Mac. That’s why you will find a separate section per operating system. Based on Java 8 I perfomed the source code adaptions to Spring 4.0.3.
Java 8 migration on Xubuntu (64bit)
This is roughly the java setup I started the migration upon:
# sym link to /etc/alternatives/java /usr/bin$ l java java -> /etc/alternatives/java --- # sym link to /usr/lib/jvm/java-7-oracle/jre/bin/java /etc/alternatives$ l java java -> /usr/lib/jvm/java-7-oracle/jre/bin/java
I used the jdk 8 download jdk-8-linux-x64.tar.gz to install Java 8. Please note, there are newer version available already at the time of writing. Check out the jdk 8 download page for more details.
The downloaded compressed file was copied to the appropriate folder, extracted and got the appropriate owner:
# move to jvm folder sudo mv jdk-8-linux-x64.tar.gz /usr/lib/jvm/ # extract archive sudo tar xvf jdk-8-linux-x64.tar.gz # owner of java executable is not root (applies to whole jdk folder) /usr/lib/jvm/jdk1.8.0/bin$ ll java 11674569 8 -rwxr-xr-x 1 uucp 143 7726 Mär 4 12:14 java # change user to root chown -hR root: /usr/lib/jvm/jdk1.8.0 /usr/lib/jvm$ ll jdk1.8.0 ... 11534384 4 drwxr-xr-x 8 root root 4096 Mär 4 12:18 . 9438979 4 drwxr-xr-x 6 root root 4096 Mär 31 22:52 .. 11668448 4 drwxr-xr-x 2 root root 4096 Mär 4 12:15 bin ...
I redirected the existing sym link that pointed to the existing jdk 1.7.x.
# delete java symlink in /etc/alternatives sudo rm java # create a new sym link that points to jdk8 sudo ln -s /usr/lib/jvm/jdk1.8.0/jre/bin/java java # double check if it worked ~$ java -version java version "1.8.0" Java(TM) SE Runtime Environment (build 1.8.0-b132) Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
My favourite IDE is IntelliJ. The ‘Selecting the JDK version the IDE will run under’ article really helped me to run IntelliJ upon jdk 1.8. The article offers several options for different operating systems how to run IntelliJ on a specific jdk. The most convenient way for me was to create an environment variable IDEA_JDK. I had to update the JAVA_HOME environment variable anyway, so the IDEA_JDK is based on that:
nano .bashrc .... JAVA_HOME=/usr/lib/jvm/jdk1.8.0 export JAVA_HOME IDEA_JDK=$JAVA_HOME export IDEA_JDK ....
Double check on command line was successful:
~$ echo $IDEA_JDK /usr/lib/jvm/jdk1.8.0 ~$ echo $JAVA_HOME /usr/lib/jvm/jdk1.8.0
The IntelliJ about screen also shows that IntelliJ runs on jdk/jre 1.8.
java 8 migration Mac (64bit)
To install Java 8 on Mac I used the jdk-8-macosx-x64.dmg installer from oracle (please check the jdk 1.8 download page for up to date downloads).
After performing the installation steps, the jdk 1.8 is installed in the same path as other already installed jdks:
/Library/Java/JavaVirtualMachines$ ls jdk1.7.0_21.jdk jdk1.7.0_51.jdk jdk1.8.0.jdk
However, the existing jdk 1.6 is located elsewhere:
/System/Library/Java/JavaVirtualMachines$ ls 1.6.0.jdk
Although the installation was succesfully finished, there was still the sym link CurrentJDK in
/System/Library/Frameworks/JavaVM.framework/Versions
that pointed to the existing 1.7.0_51 jdk:
/System/Library/Frameworks/JavaVM.framework/Versions$ l .... CurrentJDK -> /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home
I purged the existing sym link and a created a new sym link with the same name but the jdk 1.8.0 target:
sudo rm CurrentJDK sudo ln -s /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home CurrentJDK
I did also reset the JAVA_HOME environment variable:
... #JAVA_HOME #export JAVA_HOME=`/usr/libexec/java_home -v 1.7` export JAVA_HOME=`/usr/libexec/java_home -v 1.8` PATH=${JAVA_HOME}/bin:${PATH} ...
Similar to IntelliJ on Xubuntu I set IDEA_JDK environment variable on Mac as well:
... #IDEA_JDK export IDEA_JDK=$JAVA_HOME PATH=${IDEA_HOME}/bin:${PATH} ...
On Mac, you can alternatively set the JVM version in the Info.plist file of the IntelliJ App folder:
JVMVersion 1.8*
source code changes
Source code of the customHTTPcodes project applied to those files:
Almost all changes refer to both branches:
These are the changes in detail:
pom.xml
These updates happened in the pom file:
- spring version set to 4.0.3.RELEASE
<project.spring.version>4.0.3.RELEASE</project.spring.version>
- compiler version set to 1.8
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target>
- Geronimo 3 specs replace javax servlet api
<dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-servlet_3.0_spec</artifactId> <version>1.0</version> </dependency>
This is to fix errors like:
... Failed tests: springTestContextPrepareTestInstance(info.lotharschulz.item.service.ItemServiceIT): javax/servlet/SessionCookieConfig ...
that was caused by the former dependency to javax servlet api 2.5 .
This SPR comment was the only tip that really helped to solve the error above.
( Unfortunately I also found a lot of other solution proposals on the web, that did not work for me e.g. upgrading to javax servlet api 3.0.1. )
The jackson version updates did not refer to spring or java update:
- jackson mapper and databind version updated
<artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version>
<artifactId>jackson-databind</artifactId> <version>2.3.1</version>
ItemServiceIT.java
- With spring 4 dependency in place I was able to replace in ItemServiceIT.testSeeOther() test method this snippet:
MockHttpServletResponse response = result.getResponse(); String location = response.getHeader("Location"); Pattern pattern = Pattern.compile(basePath + itemID); Assert.assertTrue(pattern.matcher(location).find());
with a much cleaner and shorter
.andExpect(redirectedUrl(urlhttpPrefix + basePath + itemID))
because SPR-10789 is fixed.
- Also all (at least I hope) remaining
andDo(print())
occurrences were purged.
There is one source code change that is testNG feature branch exclusive: I removed all dependencies between tests.
All test methods are now annotated with
@Test
only.
In order to make this happen, I made sure the item objects order returned by resource /rest/v1/items/ is always the same.
Therefore the value of variable itemID in ItemServiceIT.testSeeOther() test method is now id1234a (in both branches).
ItemDaoImplTest.java
Using a TreeMap in ItemDaoImplTest.selectAll() is also related to a fixed item objects order.
log4j.xml
Not related to spring or java version update, but handy in order to read only one log file is the enlarged max file size of 10000KB.
<param name="MaxFileSize" value="10000KB"/>
Running tests in IntelliJ with compiler verions 1.8 in pom.xml did cause an error that’s stack trace included:
... Caused by: java.lang.UnsupportedClassVersionError: info/lotharschulz/item/service/ItemServiceImpl : Unsupported major.minor version 52.0 ...
Setting java 1.8 as project sdk in IntelliJ solved the issue. You can do this as shown in the screen shot on the right side. Got to “File”->”Project Structure” to open this screen:
Another warning occurred when tests ran using maven:
"Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0"
I found the MAVEN_OPTS environment variable that included amongst others
"-XX:MaxPermSize=512m "
Once this option is removed, the warning above did not happen anymore.
What are your experiences with java 1.8 and spring 4 update?
links
These links consist information that were essential for the migration:
- jdk 8 download page
- installing jdk 7 on mac os x
- SPR-10789 – Provide support for pattern matching in MockMvcResultMatchers.redirectedUrl()
- Selecting the JDK version the IDE will run under
- SPR-11049 – Cannot create MockHttpSession with servlet 2.x
comment-96610 on SPR-11049 – Cannot create MockHttpSession with servlet 2.x
Leave a Reply