Nedávno jsem prováděl změny verze Javy na projektu, který používá Spring Boot. Měnil jsem verzi Javy z verze 8 na verzi 11. Nebylo to až tak strašné, jak jsem čekal (spíše naopak), přesto se ale některé komplikace objevily. V tomto příspěvku budu postupovat od chyby k chybě, tak jak se u mě objevovaly.
Změna Javy pro IDE z 1.8.0_181 na 11.0.3 způsobila tuto chybu:
Exception in thread "main" java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap') at org.springframework.boot.devtools.restart.DefaultRestartInitializer.getUrls(DefaultRestartInitializer.java:93) at org.springframework.boot.devtools.restart.DefaultRestartInitializer.getInitialUrls(DefaultRestartInitializer.java:56) at org.springframework.boot.devtools.restart.Restarter.(Restarter.java:140)
Spring Boot podporuje Javu 11 od verze 2.1. Změnil jsem tedy verzi Spring Boot z 1.5.14.RELEASE na 2.1.4.RELEASE. Zároveň jsem změnil verzi Javy z 1.8 na 11.
Tím jsem se dostal k této chybě:
Error: java: package org.springframework.boot.web.support does not exist
Nemůže najít třídu org.springframework.boot.web.support.SpringBootServletInitializer
, protože balíček org.springframework.boot.web.support
neexistuje. Třída SpringBootServletInitializer
se přesunula z balíčku org.springframework.boot.web.support
do org.springframework.boot.web.servlet.support
. Změnil jsem tedy balíček.
V projektu používám Spring Data. Tam v nové verzi došlo k přejmenování některých metod (změny v třídě CrudRepository
) a někde ke změně signatur.
T findOne(ID id)
je nyníOptional<T> findById(ID var1)
<S extends T> Iterable<S> save(Iterable<S> entities)
je nyní<S extends T> Iterable<S> saveAll(Iterable<S> var1)
void delete(Iterable<? extends T> entities)
je nynívoid deleteAll(Iterable<? extends T> var1)
Také používám Spring Batch. Zde došlo k tomu, že data uložená (serializovaná) do databáze původní verzí, nešla v nové verzi načíst (nešel deserializovat kontext):
Caused by: java.lang.IllegalArgumentException: Unable to deserialize the execution context at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:328) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE] at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow(JdbcExecutionContextDao.java:312) ~[spring-batch-core-4.1.2.RELEASE.jar:4.1.2.RELEASE] at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:94) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:61) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate$1.doInPreparedStatement(JdbcTemplate.java:678) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:616) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:668) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE] at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:699) ~[spring-jdbc-5.1.6.RELEASE.jar:5.1.6.RELEASE] Caused by: com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id '' as a subtype of [simple type, class java.lang.Object]: no such class found at [Source: (ByteArrayInputStream); line: 1, column: 11] (through reference chain: java.util.HashMap["map"]) at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43) ~[jackson-databind-2.9.8.jar:2.9.8] at com.fasterxml.jackson.databind.DeserializationContext.invalidTypeIdException(DeserializationContext.java:1635) ~[jackson-databind-2.9.8.jar:2.9.8]
Jelikož tam nebyla žádná důležitá data (Batch tam ukládá svá provozní a historická data), obsah tabulek jsem smazal.
Obdobné to bude, pokud jste do databáze ukládali serializovaná data. Např. jste nechali Spring Data, aby za vás ukládal LocalDate
. Ten se ukládá to datového typu bytea
(PostgreSQL) a také nepůjde v nové verzi načíst.