Quale versione di Java scegliere? Guida per server

Pubblicato il 15 min di lettura

Quale versione di Java richiede davvero la tua applicazione, quale offre realmente la tua distribuzione e come far convivere più versioni passando dall'una all'altra in modo pulito.

Su un server Java non è quasi mai un fine in sé. Sta lì perché lo richiede un server Minecraft, un Tomcat, un Jenkins o un indice di ricerca. Proprio per questo la domanda non è mai "qual è il Java migliore", ma "quale Java si aspetta questa specifica applicazione, e su questo specifico sistema operativo riesco davvero a ottenerlo". Questo articolo risponde a entrambe: con i calendari di supporto, con una tabella di disponibilità che abbiamo verificato in container reali e con la pratica quotidiana di far convivere più versioni.

In breve: quale versione per quale scopo

Se hai poco tempo, la decisione è questa:

  • Progetto nuovo, scelta libera: Java 21. È attualmente la linea LTS con il supporto più ampio, già pacchettizzata in Debian 13 e in tutte le versioni Ubuntu attuali, e praticamente ogni software server recente ci gira sopra.
  • Minecraft da 1.20.5 a 1.21.11: Java 21. Obbligatorio, senza margini.
  • Minecraft 26.1 e successive: Java 25.
  • Applicazione più vecchia che nella documentazione riporta "Java 17": prendi Java 17, non "17 o superiore". Con i modloader e i sistemi di plugin il "superiore" spesso non corrisponde alla realtà.
  • Java 8 o 11: soltanto se un'applicazione legacy lo impone. Entrambe vanno nella tua lista delle cose da sostituire.
  • Java 25: la linea LTS più recente, sensata per nuovi deployment, ma prima verifica se il tuo framework è già ufficialmente approvato per questa versione.

Per la sola installazione abbiamo guide dedicate: Installare Java 17 su Debian e Installare Java 21 su Debian. Questo articolo è la mappa che le tiene insieme.

Che cosa significa LTS e per quanto tempo le versioni ricevono manutenzione

Java esce con una nuova versione principale ogni sei mesi. La stragrande maggioranza di queste è morta dopo esattamente sei mesi: Java 22, 23, 24 e 26 non ricevono più alcun aggiornamento di sicurezza non appena arriva la versione successiva. Su un server non le vuoi.

Le uniche interessanti sono le versioni LTS (Long Term Support). Dal 2021 escono ogni due anni: 8, 11, 17, 21, 25, e la prossima sarà Java 29, prevista per settembre 2027. Solo queste linee ricevono per anni aggiornamenti di sicurezza trimestrali.

Importante è la distinzione tra Oracle e le build libere. Per l'esercizio su server prendi di regola OpenJDK dal pacchetto della distribuzione oppure Eclipse Temurin. Entrambi sono utilizzabili gratuitamente e in alcuni casi la manutenzione dura molto più a lungo che con la licenza gratuita di Oracle.

VersioneUscitaStatoBuild Temurin almeno fino a
Java 82014LTS, legacydicembre 2030
Java 112018LTS, in dismissioneottobre 2027
Java 172021LTS, molto diffusaottobre 2027
Java 212023LTS, scelta standarddicembre 2029
Java 252025LTS, attualesettembre 2031

La riga di Java 17 sorprende molti: solo fino a ottobre 2027. Java 17 sembra recente, ma è già la penultima generazione LTS. Se oggi metti in piedi un sistema destinato a restare in servizio tre anni, conviene pianificare subito con 21 o 25.

Quale versione di Java offre la tua distribuzione nei propri repository

È qui che la maggior parte delle guide in rete fallisce: scrivono "apt install openjdk-17-jre-headless" e danno per scontato che funzioni ovunque. Non è così. Abbiamo verificato la situazione dei pacchetti il 27 luglio 2026 in container appena creati.

PacchettoDebian 13Debian 12Ubuntu 24.04Ubuntu 22.04
openjdk-8-jre-headlessassenteassente8u4928u492
openjdk-11-jre-headlessassenteassente11.0.3111.0.31
openjdk-17-jre-headlessassente17.0.1917.0.1917.0.19
openjdk-21-jre-headless21.0.11assente21.0.1121.0.11
openjdk-25-jre-headless25.0.3assente25.0.325.0.3

Leggi due volte le colonne Debian. Debian 12 conosce esclusivamente Java 17. Debian 13 non conosce più Java 17, in compenso offre 21 e 25. Nelle sorgenti ufficiali Debian non esiste quindi nemmeno una versione presente su entrambe le release. Chi scrive uno script di deployment che deve girare sia su bookworm sia su trixie non può contare su un unico pacchetto.

Da questo punto di vista Ubuntu è più comodo: nel repository convivono tutte e cinque le linee LTS, sia su 22.04 sia su 24.04. Se ti serve un sistema su cui girino contemporaneamente un'applicazione legacy con Java 8 e un servizio moderno con Java 21, Ubuntu è la scorciatoia.

Nel dubbio verifica di persona invece di tirare a indovinare:

apt update
apt-cache policy openjdk-21-jre-headless
apt-cache search openjdk-

Se accanto a "Candidato" (in inglese "Candidate") compare (none), che con la localizzazione italiana viene stampato come "(nessuno)", quel pacchetto su questa distribuzione non esiste. Nella famiglia Red Hat (AlmaLinux, Rocky, RHEL, Oracle Linux) i pacchetti hanno nomi diversi, lì l'elenco si ottiene così:

dnf list java-\*-openjdk-headless
dnf install -y java-21-openjdk-headless

Per la panoramica usa dnf list e non dnf list available. Il secondo nasconde i pacchetti già installati: dopo aver installato Java 21, Java 21 non compare più nell'elenco e si finisce per cercare nel posto sbagliato. La situazione nella famiglia Red Hat, anch'essa verificata in container appena creati:

PacchettoAlmaLinux 10AlmaLinux 9, Rocky 9, Oracle 9
java-1.8.0-openjdk-headlessassentepresente
java-11-openjdk-headlessassentepresente
java-17-openjdk-headlessassentepresente
java-21-openjdk-headless21.0.12da 21.0.11 a 21.0.12
java-25-openjdk-headlesspresentepresente

AlmaLinux 10 ha quindi fatto lo stesso taglio di Debian 13, abbandonando tutto ciò che sta sotto la 21. Un dnf install java-17-openjdk-headless lì finisce con No match for argument.

headless o no, JRE o JDK

Su un server prendi sempre la variante -headless. Rinuncia alle librerie grafiche e non trascina quindi dipendenze X11, il che su un server root fa risparmiare decine di pacchetti inutili. E -jre-headless basta finché ti limiti a eseguire file JAR già pronti. Solo quando compili tu stesso o quando uno strumento richiama javac ti serve openjdk-21-jdk-headless.

Nella famiglia Red Hat, a questo punto, vale la pena dare una seconda occhiata alle dipendenze. Su AlmaLinux 9 il pacchetto java-21-openjdk-devel trascina una catena sorprendentemente lunga di pacchetti grafici, tra cui webkit2gtk3-jsc, xorg-x11-fonts, xdg-desktop-portal e wireplumber. Su un server senza interfaccia grafica non è quello che vuoi. Verifica quindi prima con dnf install --assumeno che cosa arriva davvero, e resta su java-21-openjdk-headless finché non devi compilare nulla.

Minecraft: versione del gioco e versione di Java

Minecraft è il motivo più frequente per cui qualcuno porta Java su un server e allo stesso tempo l'ambito con i requisiti più rigidi. La corrispondenza è univoca:

Minecraft Java EditionJava richiesto
da 1.6.1 a 1.11.2Java 6 o superiore
da 1.12 a 1.16.5Java 8 o superiore
da 1.17 a 1.17.1Java 16 o superiore
da 1.18 a 1.20.4Java 17 o superiore
da 1.20.5 a 1.21.11Java 21 o superiore
26.1 e successiveJava 25 o superiore

Due precisazioni che nella maggior parte delle tabelle mancano. Primo: con la 26.1 Minecraft ha abbandonato il vecchio schema 1.x ed è passato a una numerazione basata sull'anno, quindi 26.1 è la prima edizione del 2026. La 1.21.11 è stata l'ultima versione che si accontenta di Java 21.

Secondo: il "o superiore" vale per il server vanilla. Non appena entrano in gioco i modloader smette di essere affidabile. Un server Forge per la 1.20.1 è costruito su Java 17, e spostarlo su Java 21 è una delle cause più frequenti di crash proprio all'avvio, anche se il numero è "più grande". Sui server con mod prendi esattamente la versione indicata da chi ha creato il modpack.

L'implementazione pratica è nelle nostre guide Installare un server Minecraft su Debian e Avviare automaticamente un server Minecraft.

Altre applicazioni server e le loro esigenze

Al di là di Minecraft valgono a grandi linee queste regole:

  • Apache Tomcat: la 9.0.x parte da Java 8, la 10.1.x richiede almeno Java 11, la 11.0.x almeno Java 17. Tutti e tre i rami attualmente mantenuti girano senza problemi su Java 17.
  • Elasticsearch e OpenSearch: portano con sé una propria JVM. Non installare lì un Java di sistema e non impostare un JAVA_HOME globale che sovrascriva la JVM inclusa. È una classica fonte di errori dopo una "pulizia" dell'installazione Java.
  • Jenkins: le versioni attuali richiedono almeno Java 17 e girano su Java 21.
  • Keycloak, Kafka, Solr, Nexus: si orientano di volta in volta sulla penultima LTS. Controlla le release notes della versione specifica, questi progetti alzano regolarmente la soglia minima.

Non tutti i software server che si associano a Java ne hanno davvero bisogno. Il server TeamSpeak 3, per esempio, è un binario nativo e funziona senza JVM.

Far convivere più versioni di Java e passare dall'una all'altra

Su Debian e Ubuntu puoi installare quanti pacchetti OpenJDK vuoi contemporaneamente. Ognuno finisce in una directory propria sotto /usr/lib/jvm/ e non si danno fastidio a vicenda:

apt install -y openjdk-21-jre-headless openjdk-25-jre-headless
ls /usr/lib/jvm/

Quello che condividono è esattamente un file: /usr/bin/java. È un symlink gestito dal sistema delle alternative. I candidati si visualizzano così:

update-alternatives --list java
update-alternatives --display java

Questa forma, con il nome subito dopo --list, è specifica di Debian: nella famiglia Red Hat è diversa, più avanti vediamo come. Fra le due, l'output di --display è il più importante. Mostra non solo i percorsi, ma anche la modalità (auto oppure manual) e la priorità di ogni voce. Il passaggio da una versione all'altra si fa in modo interattivo con update-alternatives --config java scegliendo un numero, mentre negli script conviene fissarlo:

update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java
java -version

Non copiare mai il percorso da un tutorial altrui, prendilo da update-alternatives --list java. Il percorso mostrato sopra vale per OpenJDK dal pacchetto della distribuzione. Chi segue la sezione Temurin più avanti quella directory non ce l'ha proprio: lì si chiama /usr/lib/jvm/temurin-21-jre-amd64/bin/java, e il comando si interrompe con alternative path ... doesn't exist.

Se compili anche, javac va commutato a parte. È un passaggio che si dimentica volentieri e porta alla situazione assurda in cui si compila con Java 25 e si avvia con Java 21:

update-alternatives --set javac /usr/lib/jvm/java-21-openjdk-amd64/bin/javac
javac -version

La trappola che ti costa una nottata

Finché java resta in modalità auto, vince sempre la priorità più alta, e la priorità più alta ce l'ha la versione installata più recente. Se quindi mesi dopo aggiungi openjdk-25 perché serve a un altro servizio, alla prossima operazione sui pacchetti /usr/bin/java passa silenziosamente alla 25. Il tuo server Minecraft, che fino a quel momento girava sulla 21, dopo il riavvio successivo parte su una JVM che non hai mai scelto.

update-alternatives --set porta la voce in modalità manual e la congela. È questo il vero scopo del comando. Per tornare alla modalità automatica:

update-alternatives --auto java

La strada più robusta per i servizi resta comunque non affidarsi affatto a /usr/bin/java. Inserisci nella tua unit systemd il percorso completo: così la scelta della versione è fissata per singolo servizio e indipendente da qualsiasi cambio nelle alternative:

ExecStart=/usr/lib/jvm/java-21-openjdk-amd64/bin/java -Xms2G -Xmx4G -jar server.jar nogui

Come si presenta una unit completa lo trovi in Creare un servizio systemd. Proprio questo percorso assoluto è del resto anche il motivo per cui a volte un servizio non segue un cambio di Java: update-alternatives semplicemente non lo tocca.

Su AlmaLinux, Rocky Linux, RHEL e Oracle Linux lo strumento si chiama alternatives, e update-alternatives lì è solo un symlink verso di esso. Non funziona però allo stesso modo: questo --list non accetta argomenti. Un update-alternatives --list java copiato e incollato stampa soltanto il testo di aiuto e termina con codice di ritorno 2. Corretta è una di queste due righe:

alternatives --list | grep java
alternatives --display java

Anche l'output di --display è diverso: al posto di java - auto mode lì compare java - status is auto. Nella famiglia Red Hat, inoltre, i percorsi contengono il numero di versione completo, per esempio /usr/lib/jvm/java-21-openjdk-21.0.11.0.10-1.el9.x86_64, e non la forma breve di Debian java-21-openjdk-amd64. Solo AlmaLinux 10 crea in più un symlink breve java-21-openjdk.

E lì l'automatismo si comporta in modo diverso da come ci si aspetta: dopo l'installazione di Java 17 accanto a un Java 21 già presente, su AlmaLinux 9 alternatives ha spostato da solo il link /usr/bin/java sulla 17, cioè sulla versione più vecchia. Dopo ogni installazione aggiuntiva imposta quindi esplicitamente alternatives --set java <percorso> e controlla con java -version.

Quando la distribuzione non ha la versione: Temurin

Per i buchi nella tabella qui sopra esiste una risposta pulita: Eclipse Temurin di Adoptium fornisce da temurin-8 a temurin-26 per trixie, bookworm, noble e jammy. Così ottieni Java 21 anche su Debian 12 e Java 17 anche su Debian 13, senza PPA di terzi né tarball copiati a mano in /opt.

Tieni presente che apt-key è deprecato. La chiave va in /etc/apt/keyrings/ e viene referenziata tramite signed-by:

apt install -y wget gnupg ca-certificates apt-transport-https
install -d -m 0755 /etc/apt/keyrings
wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public | gpg --dearmor | tee /etc/apt/keyrings/adoptium.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/adoptium.gpg] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list
apt update
apt install -y temurin-21-jre

Anche i pacchetti Temurin si registrano nel sistema delle alternative, compaiono quindi in update-alternatives --display java e si possono mescolare con i pacchetti OpenJDK della distribuzione. Le loro directory si trovano sotto /usr/lib/jvm/temurin-21-jre-amd64 oppure hanno nomi analoghi.

I messaggi di errore alla lettera e che cosa significano

E: Unable to locate package openjdk-17-jre-headless
Quella versione in questa distribuzione non esiste. Su Debian 13 è la normalità per Java 8, 11 e 17. Non è un errore di battitura né un apt update dimenticato: prendi Temurin o un'altra versione.

java.lang.UnsupportedClassVersionError: ... has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 61.0
Il grande classico. L'applicazione è stata costruita per una JVM più recente di quella che hai avviato. I numeri si traducono così:

class file versionJava
52.08
55.011
60.016
61.017
65.021
69.025

65.0 contro 61.0 significa quindi, in parole povere: il software vuole Java 21, tu stai facendo girare Java 17. Sui server Minecraft dalla 1.20.5 in poi vedi spesso questo errore mascherato da Error: LinkageError occurred while loading main class net.minecraft.bundler.Main, la causa vera sta poi nella riga sotto.

java: command not found
Non c'è nessuna JVM installata, oppure hai solo scompattato una directory JDK in /opt senza registrarla. Controlla con ls /usr/lib/jvm/. Se lì ci sono directory ma manca /usr/bin/java, registra la voce a posteriori:

update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-21-openjdk-amd64/bin/java 2111

update-alternatives: error: no alternatives for java
Il sistema delle alternative non conosce alcun candidato. Succede quando Java è stato installato a mano. Stessa correzione del punto precedente.

update-alternatives: error: alternative path /usr/lib/jvm/... doesn't exist
Hai impostato un percorso che nel frattempo è sparito, tipicamente dopo una disinstallazione. Ricorda che i percorsi Debian contengono l'architettura: java-21-openjdk-amd64, non java-21-openjdk.

Il servizio gira, ma sulla versione sbagliata.
Molto probabilmente nella unit systemd c'è un percorso assoluto, oppure la unit imposta un proprio JAVA_HOME. Entrambe le cose scavalcano update-alternatives senza alcun avviso.

Il server si avvia, ma muore dopo pochi secondi senza un messaggio comprensibile.
Nelle applicazioni Java spesso non è un problema di versione, ma di memoria: il kernel termina il processo quando -Xmx è impostato più in alto della RAM libera. In proposito trovi i nostri articoli Configurare lo swap contro l'Out of Memory e Disco pieno su Linux, come liberare spazio.

Come capire che gira davvero la versione giusta

La prima verifica è banale, ma falla comunque dopo ogni cambio:

java -version

L'output deve riportare la versione principale attesa, per esempio openjdk version "21.0.11". La seconda verifica è la più significativa, perché mostra il percorso realmente risolto e quindi anche se hai preso Temurin oppure l'OpenJDK della distribuzione:

readlink -f "$(command -v java)"

Qui usa volutamente command -v e non which. which è un programma esterno e nell'installazione minima di AlmaLinux 9 e 10, Rocky Linux 9 e Oracle Linux 9 non è nemmeno incluso. La variante con which lì finisce con which: command not found, seguito da readlink: missing operand. command -v è invece un builtin della shell e funziona su tutte le distribuzioni citate.

E se vuoi sapere che cosa pensa la JVM stessa della propria casa, perché un'applicazione valuta JAVA_HOME:

java -XshowSettings:properties -version

Nell'output interessano java.home e java.version. Se java.home si discosta da quello che ti aspetti, da qualche parte c'è un JAVA_HOME impostato che ha la meglio.

Per un servizio in esecuzione alla fine conta solo che cosa usa il processo stesso. Lo leggi direttamente dall'elenco dei processi, dove compare il percorso completo della JVM con cui è stato avviato:

ps -eo pid,args | grep '[j]ava'

Se lì vedi /usr/lib/jvm/java-21-openjdk-amd64/bin/java, la questione è chiusa. Se vedi un semplice java, il tuo servizio è appeso al symlink delle alternative e cambia insieme a lui. Per un servizio in produzione è la peggiore delle due varianti.

Se comunque stai configurando un server da zero, prima vale la pena dare un'occhiata alla nostra Checklist per nuovi server root: Java va alla fine di quella lista, non all'inizio, perché solo con un accesso SSH funzionante, il firewall e il fuso orario a posto la ricerca di errori su una JVM ha davvero senso.

In sintesi

Oggi Java 21 è la risposta standard, Java 25 quella a prova di futuro, Java 17 quella in uscita di scena, mentre Java 8 e 11 sono debito di migrazione. Decisivo però non è il numero da solo, ma la combinazione tra applicazione e distribuzione: Debian 12 ti dà solo la 17, Debian 13 solo la 21 e la 25, Ubuntu ti dà tutto. Dove manca il pacchetto, Temurin colma il buco. E non appena sulla macchina c'è più di una versione vale la regola: update-alternatives --set al posto dell'automatismo, e nelle unit systemd meglio subito il percorso assoluto.

Domande frequenti

Quale versione di Java conviene installare nel 2026 su un nuovo server?
Java 21, se hai libertà di scelta. È la linea LTS con il supporto più ampio, è già pronta nei repository di Debian 13 e di Ubuntu 22.04 e 24.04, e secondo Adoptium riceve build almeno fino a dicembre 2029. Java 25 è la linea LTS più recente ed è sensata non appena la tua applicazione è ufficialmente approvata per questa versione.
Perché su Debian 13 non trovo openjdk-17-jre-headless?
Perché lì quel pacchetto non esiste. Debian 13 fornisce esclusivamente openjdk-21 e openjdk-25, mentre Debian 12 fornisce esclusivamente openjdk-17. Il messaggio E: Unable to locate package openjdk-17-jre-headless è quindi corretto e non dipende da un tuo errore. In questo caso usa i pacchetti Temurin di Adoptium, che offrono da temurin-8 a temurin-26 per trixie e bookworm.
Quale versione di Java serve al mio server Minecraft?
Da 1.12 a 1.16.5 serve Java 8, per 1.17 e 1.17.1 Java 16, da 1.18 a 1.20.4 Java 17, da 1.20.5 a 1.21.11 Java 21 e dalla 26.1 in poi Java 25. Il rispettivo o superiore vale per il server vanilla; con Forge, NeoForge e i modpack prendi esattamente la versione indicata dall'autore.
Posso installare più versioni di Java contemporaneamente?
Sì. I pacchetti OpenJDK finiscono ognuno in una directory propria sotto /usr/lib/jvm/ e non si danno fastidio. L'unica cosa condivisa è il symlink /usr/bin/java, che fissi con update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java. Non dimenticare javac, che va commutato a parte.
Che cosa significa UnsupportedClassVersionError con class file version 65.0?
L'applicazione è stata costruita con una JVM più recente di quella con cui la avvii. 52.0 corrisponde a Java 8, 55.0 a Java 11, 61.0 a Java 17, 65.0 a Java 21 e 69.0 a Java 25. Se nel messaggio compare 65.0 contro 61.0, il software vuole Java 21 mentre sta girando su Java 17.
Perché dopo il cambio il mio servizio usa ancora la vecchia versione di Java?
Perché update-alternatives modifica soltanto /usr/bin/java. Se nella tua unit systemd c'è un percorso assoluto come /usr/lib/jvm/java-17-openjdk-amd64/bin/java oppure un JAVA_HOME proprio, è quello a prevalere. Verifica con ps -eo pid,args | grep '[j]ava' quale binario usa davvero il processo in esecuzione.
Per quanto tempo Java 17 riceverà ancora manutenzione?
Eclipse Temurin garantisce build per Java 17 almeno fino a ottobre 2027, quindi esattamente quanto per Java 11. Java 17 sembra recente, ma è già la penultima generazione LTS. Per sistemi destinati a restare in servizio diversi anni conviene pianificare subito con Java 21 o 25.

Java OpenJDK LTS Minecraft Debian Ubuntu update-alternatives Temurin Manutenzione server