Oppgrader en kritisk Java 8-applikasjon i etapper: lag en oversikt over alle avhengigheter, gå først til Java 11 og deretter til hver senere versjon med langtidsstøtte (LTS), og la tester og lasttester avgjøre når hvert steg er trygt. Mesteparten av arbeidet ligger i biblioteker, byggverktøy og kode som berører JDK-ens interne deler, ikke i forretningslogikken din.
Å bli værende på Java 8 gir deg færre valg for hvert år
En Java 8-applikasjon kan fortsette å kjøre i årevis, og det er fellen. Sikkerhetsoppdateringer avhenger i økende grad av en betalt supportavtale eller en distribusjon som fortsatt tilbakefører dem, og store biblioteker har gått videre. Spring Boot 3 krever for eksempel minst Java 17, så å bli værende på Java 8 fryser også rammeverksversjonene dine.
Nyere JVM-er kjører også den samme koden bedre. G1 har vært standard søppeloppsamler siden Java 9, oppsamlere med korte pauser som ZGC er klare for produksjon, og kompakte strenger reduserer minnebruken for arbeidslaster med mye tekst. Utviklere forventer dessuten moderne språkfunksjoner som records, text blocks og switch-uttrykk, noe som gjør det vanskeligere å bemanne en kodebase i Java 8.
Start med en oversikt over alt applikasjonen er avhengig av
Selve JDK-oppgraderingen er sjelden det vanskelige. Det vanskelige er den lange halen av biblioteker, plugins og agenter som ble skrevet for Java 8 og aldri oppdatert. Lag en fullstendig liste før du endrer noe, og registrer versjonen av hvert element.
- JDK-leverandøren og -versjonen i hvert miljø, fra utviklernes bærbare maskiner til produksjon.
- Direkte og transitive avhengigheter, eksportert fra avhengighetstreet i Maven eller avhengighetsrapporten i Gradle.
- Bygg-plugins, kodegeneratorer og annotasjonsprosessorer som Lombok.
- Applikasjonsserveren eller servlet-containeren, hvis applikasjonen kjører i en slik.
- Java-agenter for overvåking, profilering eller sikkerhet, som kobler seg dypt inn i JVM-en.
- Kode som bruker interne JDK-API-er, funnet med verktøyet jdeps og opsjonen jdk-internals.
- JVM-flagg, innstillinger for søppeloppsamleren og eventuelle skript som leser utdataene fra java -version.
Gå trinnvis gjennom LTS-versjonene i stedet for å hoppe
Gå fra Java 8 til 11, deretter til 17, og så til 21 eller 25. Hvert hopp har sine egne fjerninger og endringer i oppførsel, og ett stort hopp blander dem alle sammen til én feil du ikke kan diagnostisere. Når du retter ett lag om gangen, blir hvert steg lite nok til å gjennomgås og rulles tilbake.
Der du kan, bør du oppgradere biblioteker mens du fortsatt er på Java 8, siden mange nyere versjoner støtter både gamle og nye JDK-er. Kjør deretter det eksisterende bygget på den nye JVM-en før du endrer kompileringsmålet. Dette skiller problemer ved kjøring fra problemer i kompilatoren, og kompilatorflagget release holder bytekodemålet eksplisitt.
La testsuiten være porten for hvert steg
Tester er det eneste objektive signalet på at den oppgraderte applikasjonen fortsatt oppfører seg likt. Hvis de kritiske flytene har lav dekning, bør du først skrive karakteriseringstester: tester som fanger opp hva systemet gjør i dag, inkludert de rare grensetilfellene, uten å vurdere om oppførselen er riktig.
Legg til integrasjonstester som kjører mot en ekte database og ekte meldingsmeglere, fordi mange feil ved oppgradering bare viser seg ved disse grensesnittene. For systemer med mye beregning kan du spille av de samme inndataene gjennom den gamle og den nye versjonen og sammenligne resultatene felt for felt. Vær oppmerksom på datoer, tall og tekst: Java 9 gikk over til lokaliseringsdata fra CLDR som standard, og Java 18 gjorde UTF-8 til standard tegnsett, og begge deler kan endre formatering eller tolkning uten at det merkes.
Kjenn fallgruvene som ødelegger Java 8-kode
De fleste feilene faller inn i noen få kjente kategorier. Søk etter hver av dem før oppgraderingen i stedet for å oppdage dem i produksjon.
- Fjernede Java EE- og CORBA-moduler: Java 11 fjernet JAXB, JAX-WS, JavaBeans Activation og common annotations fra JDK-en, så de må legges til igjen som eksplisitte avhengigheter.
- Sterk innkapsling av JDK-ens interne deler: ulovlig refleksiv tilgang ga advarsler fra Java 9, blir avvist som standard siden Java 16 og kan ikke slås på igjen globalt siden Java 17. Løs det ved å oppgradere biblioteket; bruk add-opens bare som et dokumentert, midlertidig unntak.
- Utdaterte bytekodeverktøy: eldre versjoner av Lombok, Mockito, Byte Buddy, ASM og bygg-plugins feiler på nyere versjoner av klassefilformatet.
- Fjernede funksjoner: JavaScript-motoren Nashorn ble fjernet i Java 15, og Security Manager ble avviklet i Java 17 og slått permanent av i Java 24.
- Fjernede JVM-flagg: søppeloppsamleren CMS ble fjernet i Java 14, og en JVM som startes med fjernede opsjoner, kan nekte å starte.
Bevis ytelsen under realistisk belastning, ikke på en bærbar maskin
En ny JDK endrer søppeloppsamleren, JIT-kompilatoren og minneoppsettet, så ytelsen kan gå i begge retninger. Kjør en lasttest som gjenskaper trafikkprofilen fra produksjon, på samme maskinvare eller instanstype, før og etter hvert steg. Sammenlign persentiler for latens, gjennomstrømning, minne og pauser i søppeloppsamlingen, og la JIT-kompilatoren varme opp før du måler.
Utviklerne våre ledet en migrering fra Java 8 til 16 av en kritisk applikasjon for dagshandel med gass for en nasjonal handelsdesk for gass, gjennom Sopra Steria. På det systemet måtte beregningene av kapasitet og energiflyt forbli riktige og raske under høyfrekvent belastning, så oppgraderingen gikk hånd i hånd med optimalisering av disse beregningene og ble validert under belastning i stedet for å bli tatt for gitt.
Rull ut gradvis, og behold en vei tilbake
Send det oppgraderte kjøremiljøet først til én instans eller en liten andel av trafikken, og følg med på feilrater, latens og oppførselen til søppeloppsamlingen sammenlignet med utgangspunktet på Java 8. Behold det forrige bygget klart for utrulling til den nye versjonen har gått gjennom normale forretningssykluser, inkludert månedsslutt eller perioder med toppbelastning.
Først da fjerner du Java 8-artefaktene og begynner å bruke nye språkfunksjoner. Hvis du vil ha hjelp til å planlegge eller gjennomføre en slik oppgradering, bemanner SDK Enterprises den med egne utviklere og kvalitetssikrede spesialister under én kontrakt med ett ansvarlig selskap.
Det viktigste
- Innsatsen i en oppgradering fra Java 8 ligger mest i avhengigheter, byggverktøy og bruk av JDK-ens interne deler, ikke i forretningslogikken.
- Gå gjennom LTS-versjonene én om gangen, slik at hver feil har én årsak som kan finnes.
- Karakteriserings- og integrasjonstester er porten for hvert steg, særlig rundt datoer, tall og tegnkoding.
- Valider ytelsen under en belastning som ligner produksjon, fordi endringer i søppeloppsamling og JIT kan trekke resultatene i begge retninger.
- Rull først ut til en liten andel av trafikken, og behold Java 8-bygget klart for utrulling til det nye kjøremiljøet har vist seg pålitelig.
Spørsmål og svar
Kan jeg oppgradere direkte fra Java 8 til Java 21?
Det kan du, men da arver du alle endringene fra Java 9 til 21 på én gang, noe som gjør feil vanskelige å spore. Å gå trinnvis via 11 og 17 koster litt mer byggetid og sparer mye feilsøking på et kritisk system.
Hvor lang tid tar en oppgradering fra Java 8?
Det avhenger av antall avhengigheter, hvor mange av dem som bruker JDK-ens interne deler, testdekningen og hvor mye lasttesting systemet trenger. En oversikt og en prøvekjøring på den nye JVM-en gir deg tidlig et realistisk estimat, før du forplikter deg til en tidsplan.
Må jeg skrive om koden for å bruke nye Java-funksjoner?
Nei. Java har sterk bakoverkompatibilitet for kode som holder seg til standard API-er som ikke er avviklet. Ta i bruk records, text blocks og andre funksjoner gradvis, etter at det oppgraderte kjøremiljøet er stabilt i produksjon.