[Linkset] Migration to Java 8


Notes from Oracle http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html

Also possible problems:

  • switching to 64bit JVM can require more memory (actually as I know it was only in few builds of Oracle JDK 6 and all next versions comes with enabled flag -XX:+UseCompressedOops)
  • changes in garbage collection can lead to unexpected pauses
  • inclusion of XML parsers into JDK proper requires changes to web application packaging or configuration
  • memory and runtime characterics of String#substring completely change in «minor» JDK revision
  • sorting a collection with a custom (incorrectly implemented) comparator suddenly throws exceptions it did not throw before  (Java error: Comparison method violates its general contract)
  • Calling Thread#stop(Throwable) (which was never a good idea and has been deprecated for a very long time) throws a UnsupportedOperationException since Java 8
  • Updated Unicode support changing sorting and casing behavior for some strings
  • Changes in generics compilation
  • inability to extend BitSet and implement Set<Integer> due to new default methods
  • Bigin rounding behavior (affected early builds of JDK7 and JDK8)

http://stackoverflow.com/questions/28228450/java-is-backward-compatible-but-why-we-need-to-upgrade-many-libraries-when-we-u

Also I tried to mark all this issues on StackOverflow with tags migration+java-8 and migration+java-7

Most valuable article http://product.hubspot.com/blog/upgrading-to-java-8-at-scale
Key points: you need to update ASM lib and use cglib-nodep where possible.

Managing compatibility

See linkset [LinkSet] Compatibility
Tool for checking API and BPI http://ispras.linuxbase.org/index.php/Java_API_Compliance_Checker
http://wiki.apidesign.org/wiki/SignatureTests
https://stackoverflow.com/questions/2040693/how-to-identify-a-missing-method-binary-compatibility-in-a-jar-statically
http://clirr.sourceforge.net/
http://www.sab39.org/Software/Japitools/42/
http://tattletale.jboss.org/

How Spring achieves compatibility with Java 6, 7 and 8

And don’t forget to enable -parameters option https://julien.ponge.org/blog/java8-parameter-names-and-jdk-dogfooding/

https://stackoverflow.com/questions/8111310/java-7-jdk-7-garbage-collection-and-documentation

http://allegrotech.io/How-to-migrate-to-Java-8.html

https://www.techempower.com/blog/2013/03/26/everything-about-java-8/

http://zeroturnaround.com/rebellabs/what-migrating-to-java-8-will-do-to-your-codebase-a-practical-example/

In some cases it possible speed downgrade
https://stackoverflow.com/questions/23756966/why-is-stringbuilderappendint-faster-in-java-7-than-in-java-8

Also from my experience of migration from JDK6 to JDK8:

1 . APT (Annotations Processing Tool) was removed. We used Enunciate for Web Services and it uses APT. So now we waiting next version of Enunciate that will use JSR 269 instead of APT.

And actually there was a lot of API that was removed from Java and in first link Oracle told about it just see «Features Removed from Java SE 8» and «Features Removed from JDK 8».

2 . java.util.Locale class was updated and it causes error in our application.
We have some users with ISO country code CS i.e. Serbia and Montenegro. In 2004 Montenegro separated from Serbia and this code CS was removed in new version of Locale.getISOCountries().
Since our application had checks on this code we got a lot of exceptions.

3 . maven-tomcat-plugin hasn’t yet version for Tomcat 8. You can vote or contribute MTOMCAT-234. And in Tomcat 8 in some configs we needed to change path starting with root /

4 . HashMap descendants should keep contract between put() and putAll()
All classes that extends HashMap and overrides `put() method may have errors if not overrides putAll() method.
You can see interest bug in Spring framework for details https://jira.spring.io/browse/SPR-7969.

5 . Clashing Getters.
Also we had an error when our domain classes contains two getters for the same property.
For example, class MerchantData contains two methods getParentMerchant() and isParentMerchant()

public void setParentMerchant(MerchantData parentMerchant) {
this.parentMerchant = parentMerchant;
}

public MerchantData getParentMerchant() {
return parentMerchant;
}

public boolean isParentMerchant() {
return subMerchants != null && !subMerchants.isEmpty();
}

According to JavaBeans specification all getters of boolean properties should be named isSomething().
Hibernate tries to determine the type of property parentMerchant and it looks that type is Boolean.
Then he tries to get id of parentMerchant ant fail with error:

Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.example.merchant.dao.MerchantData.id
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)

To fix that we need to rename method isParentMerchant() or get rid of it.
This kind of issues are happened only when we run project on JDK8.
So, please take it into account when you create a new getters.

I asked guys from JetBrains to make inspection for IntelliJ that reports about this potential bugs, please vote.
Also I created plugin https://github.com/stokito/IntellijClashingGettersInspection

Something similar Why did PropertyDescriptor behavior change from Java 1.6 to 1.7?

6 . Groovy code may fails with java.lang.IncompatibleClassChangeError during constructing exceptions that was compiled in Java 6. Good article How to fix IncompatibleClassChangerError with groovy on jdk7
It’s very often error in Grails applications

7 . Maven is not working in Java 8 when JavaDoc tags are incomplete
You can easily find all this incomplete tags in IntelliJ by running inspection Ctrl+Alt+Shift+i «Declaration has JavaDoc problems»
Also there was few other errors in maven plugins, most of them already fixed but check them anyway
https://cwiki.apache.org/confluence/display/MAVEN/Java+8+Upgrade

8 . ActiveMQ still has a bug that occurs only in JDK 8 AMQ-5356 Unable to see message contents from the web UI

9 . You really should resolve your JAR HELL before upgrading.

Also known bug:
Xstream no-args constructor error

Tutorial: Migrating to Java 8

Migration plan:

  1. Make build stable: migrate to the latest Maven, introduce Continuous Integration.
  2. Resolve JAR hell, explicitly define all libraries and plugins versions.
  3. Improve test coverage, take care to rounding of BigDecimal, working with dates, localization (country codes and time zones),  Comparators, XML parsing,  Reflection and serialization. Integration tests for all parts of application that using external JAR’s or classes for example database  (JDBC drivers).
  4. Fix basic and common errors: clashing geters, missing @Override annotations.
  5. Upgrade all bytecode-level manipulation libraries (CGLIB, ASM, JavaAssist)
  6. Try to compile with old JDK (6, 7) but try to run with new JDK (8, 9).
  7. Run all regression tests and fix all bugs that you’ll find.
  8. Upgrade other core libraries (Hibernate, Spring, JDBC divers) and try to remove obsolete (com.sun package)
  9. Test again and fix new founded bugs.
  10. Then try to compile with new JDK (8,9) but with target language level 6. But still run with new one.
  11. Test again and fix new founded bugs.
  12. Then try to compile with new JDK (8,9) and with last target language level (8, 9). And run with last.
  13. Test again and fix new founded bugs. Migration finished
Реклама

One comment

  1. Уведомление: Dependencies Hell: Конфликт зависимостей и версионные выбоины | stokito on software

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s