Μετάβαση στο περιεχόμενο
SDK.

Οδηγοί

Αναβάθμιση κρίσιμης εφαρμογής Java 8 σε σύγχρονη Java

· 6 λεπτά ανάγνωσης

Αναβαθμίστε μια κρίσιμη εφαρμογή Java 8 σε στάδια: απογράψτε κάθε εξάρτηση, περάστε πρώτα στη Java 11 και μετά σε κάθε επόμενη έκδοση μακροχρόνιας υποστήριξης (LTS), και αφήστε τα τεστ και τις δοκιμές φορτίου να αποφασίζουν πότε κάθε βήμα είναι ασφαλές. Το μεγαλύτερο μέρος της δουλειάς βρίσκεται στις βιβλιοθήκες, στα εργαλεία build και στον κώδικα που αγγίζει τα εσωτερικά του JDK, όχι στην επιχειρησιακή σας λογική.

Η παραμονή στη Java 8 στενεύει τις επιλογές σας κάθε χρόνο

Μια εφαρμογή Java 8 μπορεί να συνεχίσει να τρέχει για χρόνια, και αυτή είναι η παγίδα. Οι διορθώσεις ασφαλείας εξαρτώνται όλο και περισσότερο από ένα πληρωμένο συμβόλαιο υποστήριξης ή από μια διανομή που εξακολουθεί να τις μεταφέρει προς τα πίσω, και οι μεγάλες βιβλιοθήκες έχουν προχωρήσει. Το Spring Boot 3, για παράδειγμα, απαιτεί τουλάχιστον Java 17, οπότε η παραμονή στη Java 8 παγώνει και τις εκδόσεις του framework σας.

Οι νεότερες JVM τρέχουν επίσης καλύτερα τον ίδιο κώδικα. Ο G1 είναι ο προεπιλεγμένος garbage collector από τη Java 9, collectors χαμηλών παύσεων όπως ο ZGC είναι έτοιμοι για παραγωγή, και τα compact strings μειώνουν τη χρήση μνήμης σε φορτία με πολύ κείμενο. Οι μηχανικοί περιμένουν επίσης σύγχρονα χαρακτηριστικά της γλώσσας, όπως records, text blocks και switch expressions, κάτι που κάνει δυσκολότερη τη στελέχωση μιας βάσης κώδικα Java 8.

Ξεκινήστε με απογραφή όλων όσων χρειάζεται η εφαρμογή

Η ίδια η αναβάθμιση του JDK σπάνια είναι το δύσκολο κομμάτι. Το δύσκολο είναι η μακριά ουρά βιβλιοθηκών, plugins και agents που γράφτηκαν για τη Java 8 και δεν ενημερώθηκαν ποτέ. Φτιάξτε μια πλήρη λίστα πριν αλλάξετε οτιδήποτε και καταγράψτε την έκδοση κάθε στοιχείου.

  • Τον πάροχο και την έκδοση του JDK σε κάθε περιβάλλον, από τους φορητούς υπολογιστές των προγραμματιστών μέχρι την παραγωγή.
  • Άμεσες και μεταβατικές εξαρτήσεις, εξαγμένες από το dependency tree του Maven ή την αναφορά dependencies του Gradle.
  • Plugins του build, γεννήτριες κώδικα και annotation processors όπως το Lombok.
  • Τον application server ή τον servlet container, αν η εφαρμογή τρέχει μέσα σε κάποιον.
  • Java agents για παρακολούθηση, profiling ή ασφάλεια, που συνδέονται σε βάθος με τη JVM.
  • Κώδικα που χρησιμοποιεί εσωτερικά API του JDK, τον οποίο εντοπίζετε με το εργαλείο jdeps και την επιλογή του jdk-internals.
  • Σημαίες της JVM, ρυθμίσεις του garbage collector και κάθε script που αναλύει την έξοδο του java -version.

Περάστε από τις εκδόσεις μακροχρόνιας υποστήριξης αντί να πηδήξετε

Περάστε από τη Java 8 στην 11, μετά στη 17, μετά στη 21 ή στην 25. Κάθε βήμα έχει τις δικές του αφαιρέσεις και αλλαγές συμπεριφοράς, και ένα μόνο άλμα τις ανακατεύει όλες σε μια αποτυχία που δεν μπορείτε να διαγνώσετε. Η διόρθωση ενός επιπέδου τη φορά κρατά κάθε βήμα αρκετά μικρό για να ελεγχθεί και να αναιρεθεί.

Όπου μπορείτε, αναβαθμίστε τις βιβλιοθήκες όσο είστε ακόμη στη Java 8, αφού πολλές πρόσφατες εκδόσεις υποστηρίζουν και παλιά και νέα JDK. Μετά τρέξτε το υπάρχον build στη νέα JVM πριν αλλάξετε τον στόχο μεταγλώττισης. Έτσι ξεχωρίζετε τα προβλήματα εκτέλεσης από τα προβλήματα του compiler, και η σημαία release του compiler κρατά ρητό τον στόχο του bytecode.

Κάντε τη σουίτα τεστ πύλη για κάθε βήμα

Τα τεστ είναι το μόνο αντικειμενικό σήμα ότι η αναβαθμισμένη εφαρμογή συμπεριφέρεται ακόμη με τον ίδιο τρόπο. Αν οι κρίσιμες διαδρομές έχουν μικρή κάλυψη, γράψτε πρώτα τεστ χαρακτηρισμού: τεστ που καταγράφουν τι κάνει σήμερα το σύστημα, μαζί με τις παράξενες οριακές περιπτώσεις του, χωρίς να κρίνουν αν αυτή η συμπεριφορά είναι σωστή.

Προσθέστε τεστ ενσωμάτωσης που τρέχουν πάνω σε πραγματική βάση δεδομένων και πραγματικούς message brokers, γιατί πολλές αποτυχίες αναβάθμισης εμφανίζονται μόνο σε αυτά τα όρια. Για συστήματα με πολλούς υπολογισμούς, περάστε τις ίδιες εισόδους από την παλιά και τη νέα έκδοση και συγκρίνετε τις εξόδους πεδίο προς πεδίο. Προσέξτε τις ημερομηνίες, τους αριθμούς και το κείμενο: η Java 9 πέρασε εξ ορισμού στα δεδομένα τοπικών ρυθμίσεων CLDR και η Java 18 έκανε το UTF-8 προεπιλεγμένη κωδικοποίηση, και τα δύο μπορούν να αλλάξουν αθόρυβα τη μορφοποίηση ή την ανάλυση.

Γνωρίστε τις παγίδες που σπάνε τον κώδικα Java 8

Οι περισσότερες αποτυχίες ανήκουν σε λίγες γνωστές κατηγορίες. Αναζητήστε την καθεμία πριν από την αναβάθμιση αντί να την ανακαλύψετε στην παραγωγή.

  • Αφαιρεμένα modules Java EE και CORBA: η Java 11 αφαίρεσε από το JDK τα JAXB, JAX-WS, JavaBeans Activation και τα common annotations, οπότε πρέπει να προστεθούν ξανά ως ρητές εξαρτήσεις.
  • Ισχυρή ενθυλάκωση των εσωτερικών του JDK: η μη επιτρεπτή πρόσβαση μέσω reflection έβγαζε προειδοποιήσεις από τη Java 9, απορρίπτεται εξ ορισμού από τη Java 16 και δεν μπορεί να ενεργοποιηθεί ξανά καθολικά από τη Java 17. Διορθώστε την αναβαθμίζοντας τη βιβλιοθήκη· χρησιμοποιήστε το add-opens μόνο ως τεκμηριωμένη, προσωρινή εξαίρεση.
  • Παρωχημένα εργαλεία bytecode: παλαιότερες εκδόσεις των Lombok, Mockito, Byte Buddy, ASM και plugins του build αποτυγχάνουν σε νεότερες εκδόσεις αρχείων class.
  • Αφαιρεμένες δυνατότητες: η μηχανή JavaScript Nashorn αφαιρέθηκε στη Java 15, και ο Security Manager χαρακτηρίστηκε παρωχημένος στη Java 17 και απενεργοποιήθηκε οριστικά στη Java 24.
  • Αφαιρεμένες σημαίες JVM: ο garbage collector CMS αφαιρέθηκε στη Java 14, και μια JVM που ξεκινά με επιλογές που έχουν αφαιρεθεί μπορεί να αρνηθεί να εκκινήσει.

Αποδείξτε την απόδοση υπό ρεαλιστικό φορτίο, όχι σε ένα laptop

Ένα νέο JDK αλλάζει τον garbage collector, τον JIT compiler και τη διάταξη της μνήμης, οπότε η απόδοση μπορεί να κινηθεί προς οποιαδήποτε κατεύθυνση. Τρέξτε μια δοκιμή φορτίου που αναπαράγει το προφίλ κίνησης της παραγωγής, στο ίδιο υλικό ή στον ίδιο τύπο instance, πριν και μετά από κάθε βήμα. Συγκρίνετε τα εκατοστημόρια καθυστέρησης, τον ρυθμό επεξεργασίας, τη μνήμη και τις παύσεις του garbage collection, και αφήστε τον JIT να «ζεσταθεί» πριν μετρήσετε.

Οι μηχανικοί μας ηγήθηκαν της μετάβασης από Java 8 σε 16 μιας κρίσιμης εφαρμογής ενδοημερήσιας διαπραγμάτευσης φυσικού αερίου για ένα εθνικό γραφείο διαπραγμάτευσης φυσικού αερίου, μέσω της Sopra Steria. Σε εκείνο το σύστημα, οι υπολογισμοί χωρητικότητας και ροών ενέργειας έπρεπε να μένουν σωστοί και γρήγοροι υπό φορτίο υψηλής συχνότητας, γι' αυτό η αναβάθμιση συνοδεύτηκε από εργασίες βελτιστοποίησης αυτών των υπολογισμών και επικυρώθηκε υπό φορτίο αντί να θεωρηθεί δεδομένη.

Κάντε σταδιακή διάθεση και κρατήστε δρόμο επιστροφής

Βγάλτε το αναβαθμισμένο περιβάλλον εκτέλεσης πρώτα σε ένα instance ή σε ένα μικρό μέρος της κίνησης, και παρακολουθήστε τα ποσοστά σφαλμάτων, την καθυστέρηση και τη συμπεριφορά του garbage collection σε σύγκριση με τη βάση αναφοράς της Java 8. Κρατήστε το προηγούμενο build έτοιμο για deploy μέχρι η νέα έκδοση να περάσει από κανονικούς επιχειρησιακούς κύκλους, μαζί με το κλείσιμο του μήνα ή τις περιόδους αιχμής.

Μόνο τότε αφαιρέστε τα artifacts της Java 8 και αρχίστε να χρησιμοποιείτε τα νέα χαρακτηριστικά της γλώσσας. Αν θέλετε βοήθεια για να σχεδιάσετε ή να υλοποιήσετε μια τέτοια αναβάθμιση, η SDK Enterprises τη στελεχώνει με τους δικούς της μηχανικούς και ελεγμένους ειδικούς, υπό μία σύμβαση με σαφή ευθύνη.

Τα βασικά σημεία

  • Η προσπάθεια σε μια αναβάθμιση από Java 8 βρίσκεται κυρίως στις εξαρτήσεις, στα εργαλεία build και στη χρήση των εσωτερικών του JDK, όχι στην επιχειρησιακή λογική.
  • Περάστε από τις εκδόσεις μακροχρόνιας υποστήριξης μία μία, ώστε κάθε αποτυχία να έχει μία αιτία που βρίσκεται.
  • Τα τεστ χαρακτηρισμού και ενσωμάτωσης είναι η πύλη για κάθε βήμα, ιδίως γύρω από ημερομηνίες, αριθμούς και κωδικοποίηση κειμένου.
  • Επικυρώστε την απόδοση υπό φορτίο παρόμοιο με της παραγωγής, γιατί οι αλλαγές στο garbage collection και στον JIT μπορούν να μετακινήσουν τα αποτελέσματα προς οποιαδήποτε κατεύθυνση.
  • Διαθέστε πρώτα σε ένα μικρό μέρος της κίνησης και κρατήστε το build της Java 8 έτοιμο για deploy μέχρι το νέο περιβάλλον να αποδείξει την αξία του.

Συχνές ερωτήσεις

Μπορείτε να περάσετε απευθείας από Java 8 σε Java 21;

Μπορείτε, αλλά κληρονομείτε μονομιάς κάθε αλλαγή από τη Java 9 έως τη 21, κάτι που κάνει τις αποτυχίες δύσκολες στον εντοπισμό. Το πέρασμα από την 11 και τη 17 κοστίζει λίγο περισσότερο χρόνο build και γλιτώνει πολύ debugging σε ένα κρίσιμο σύστημα.

Πόσο διαρκεί μια αναβάθμιση από Java 8;

Εξαρτάται από τον αριθμό των εξαρτήσεων, από το πόσες χρησιμοποιούν εσωτερικά του JDK, από την κάλυψη των τεστ και από το πόσες δοκιμές φορτίου χρειάζεται το σύστημα. Μια απογραφή και μια δοκιμαστική εκτέλεση στη νέα JVM σας δίνουν νωρίς μια ρεαλιστική εκτίμηση, πριν δεσμευτείτε σε χρονοδιάγραμμα.

Χρειάζεται να ξαναγράψετε κώδικα για να χρησιμοποιήσετε τα νέα χαρακτηριστικά της Java;

Όχι. Η Java διατηρεί ισχυρή συμβατότητα προς τα πίσω για κώδικα που χρησιμοποιεί τυπικά, μη παρωχημένα API. Υιοθετήστε τα records, τα text blocks και τα άλλα χαρακτηριστικά σταδιακά, αφού το αναβαθμισμένο περιβάλλον εκτέλεσης σταθεροποιηθεί στην παραγωγή.

Πείτε μας τι χρειάζεστε.

Κάτι που θέλετε να φτιαχτεί, άνθρωποι που πρέπει να βρεθούν ή μια ερώτηση που θέλει απάντηση. Σε μια κλήση 30 λεπτών σας ακούμε και σας λέμε ειλικρινά πώς μπορούμε να βοηθήσουμε και τι θα χρειαστεί.