Nessun risultato trovato

La tua ricerca non ha prodotto risultati.

È consigliabile provare quanto segue per riuscire a trovare quello che stai cercando:

  • Controlla l'ortografia della ricerca per parola chiave.
  • Utilizza sinonimi per la parola chiave digitata, ad esempio prova “applicazione” anziché “software”.
  • Prova una delle ricerche popolari mostrate di seguito.
  • Inizia una nuova ricerca.
Domande di tendenza
 

 

Java 9 | Estratto

Introduzione ai moduli Java 9

Cosa sono e come utilizzarli

Di Paul Deitel


Paul Deitel

Paul Deitel

In questo articolo, approfondiròJava 9 Platform Module System (JPMS), ltra le più importanti nuove tecnologie di ingegneria del software in Java fin dalla sua creazione. La modularità, il risultato di Project Jigsaw, aiuta gli sviluppatori di qualsiasi livello ad essere più produttivi quando creano, mantengono ed evolvono i sistemi software, in particolare quelli di grandi dimensioni.

Che cos'è un modulo?

La modularità aggiunge un livello di aggregazione superiore ai pacchetti. Un nuovo elemento chiave del linguaggio è il modulo, che si può definire come un gruppo di pacchetti correlati con nomi univoci e riutilizzabili, così come di risorse (ad esempio immagini e file XML) e un descrittore del modulo che specifica

  • il nome del modulo
  • le sue dipendenze (ovvero altri moduli da cui esso dipende)
  • i pacchetti che rende esplicitamente disponibili ad altri moduli (tutti gli altri pacchetti nel modulo sono implicitamente non disponibili in altri moduli)
  • i servizi che offre
  • i servizi che consuma;
  • a quali altri moduli consente la riflessione

Storia

La piattaforma Java SE è attiva dal 1995. Ora ci sono circa 10 milioni di sviluppatori che lo utilizzano per creare qualsiasi cosa, dalle piccole applicazioni per dispositivi con risorse limitate, come quelle nell'Internet of Things (IoT) e altri dispositivi integrati, ai sistemi business-critical e mission-critical su larga scala. Ci sono enormi quantità di codice legacy là fuori, ma fino ad ora, la piattaforma Java è stata principalmente una soluzione monolitica one-size-fits-all. Nel corso degli anni, sono stati fatti vari tentativi improntati alla modularizzazione di Java, ma nessuno ha avuto successo.

Modularizzare la piattaforma Java SE è stato complesso e ha richiesto molti anni. JSR 277: Java Module System è stato originariamente proposto nel 2005 per Java 7. Questo JSR è stato successivamente sostituito da JSR 376: Java Platform Module System e destinato a Java 8. La piattaforma Java SE è ora modularizzata in Java 9, ma ciò è avvenuto solo dopo che Java 9 fu posticipato fino a settembre 2017.

Obiettivi

Ogni modulo deve indicare in modo esplicito le sue dipendenze.

Secondo JSR 376, gli obiettivi chiave della modularizzazione della piattaforma Java SE sono

  • Una configurazione affidabile: la modularità fornisce meccanismi per dichiarare esplicitamente le dipendenze tra i moduli in un modo che viene riconosciuto sia al momento della compilazione sia al momento dell'esecuzione. Il sistema può analizzare queste dipendenze per determinare il sottoinsieme di tutti i moduli necessari per supportare la tua applicazione.
  • Un forte incapsulamento: i pacchetti in un modulo sono accessibili ad altri moduli solo se il modulo li esporta esplicitamente. Anche in tal caso, un altro modulo non potrà utilizzare questi pacchetti a meno che non indichi esplicitamente di aver bisogno delle capacità dell'altro modulo. Ciò migliora la sicurezza della piattaforma, in quanto un numero inferiore di classi è accessibile a possibili attacchi. Ti accorgerai che la modularità può aiutarti a creare design più puliti e logici.
  • Una piattaforma Java scalabile: in passato, la piattaforma Java era un monolite costituito da un'enormità di pacchetti, il che rendeva difficile sviluppare, mantenere ed evolvere. Non poteva essere diviso facilmente in sottoinsiemi. La piattaforma è ora modularizzata in 95 moduli (questo numero potrebbe cambiare con l'evoluzione di Java). Puoi creare runtime personalizzati composti solo da moduli di cui hai bisogno per le tue applicazioni o i dispositivi a cui stai mirando. Se ad esempio un dispositivo non supporta le interfacce GUI, puoi creare un runtime che non includa i moduli GUI, riducendo in modo significativo le sue dimensioni.
  • Una maggiore integrità della piattaforma: prima di Java 9, era possibile utilizzare diverse classi nella piattaforma, il cui utilizzo non era destinato alle classi di un'applicazione. Grazie a un'efficace incapsulamento, queste API interne sono realmente incapsulate e nascoste dalle applicazioni che utilizzano la piattaforma. Questo può rendere problematica la migrazione del codice legacy a Java 9 modularizzato, se il codice dipende dalle API interne.
  • Migliori performance: JVM utilizza varie tecniche di ottimizzazione per migliorare le performance delle applicazioni. JSR 376 dimostra che queste tecniche sono più efficaci quando è noto in anticipo che i tipi richiesti si trovano solo in moduli specifici.

Elenco dei moduli di JDK

JEP 200: THE MODULAR JDK

JEP 201: MODULAR SOURCE CODE

JEP 220: MODULAR RUN-TIME IMAGES

JEP 260: ENCAPSULATE MOST INTERNAL APIS

JEP 261: MODULE SYSTEM

JEP 275: MODULAR JAVA APPLICATION PACKAGING

JEP 282: JLINK: THE JAVA LINKER

JSR 376: JAVA PLATFORM MODULE SYSTEM

JSR 379: JAVA SE 9

Tabella 1. JEP e JSR della modularità Java

Un aspetto cruciale di Java 9 sta nel dividere il JDK in moduli per supportare varie configurazioni. (Consulta "JEP 200: The Modular JDK". Tutti i processi JEP e JSR della modularità Java sono illustrati nella Tabella 1. Utilizzando il comando java della cartella bin del JDK con l'opzione --list-modules, come in: 

java --list-modules

elenca il set di moduli del JDK, che include i moduli standard i quali implementano Java Language SE Specification (nomi che iniziano con java), i moduli JavaFX (nomi che iniziano con javafx), i moduli specifici del JDK (nomi che iniziano con jdk) e i moduli specifici di Oracle (nomi che iniziano con oracle). Ogni nome del modulo è seguito da una stringa di versione: @9 indica che il modulo appartiene a Java 9.

Dichiarazioni modulo

Come accennato, un modulo deve fornire un descrittore del modulo, ovvero dei metadati che specifichino le dipendenze del modulo, i pacchetti che il modulo rende disponibili ad altri moduli e altro ancora. Un descrittore del modulo è la versione compilata di una dichiarazione del modulo definita in un file chiamato module-info.java. Ogni dichiarazione del modulo inizia con la parola chiave module, seguita da un nome univoco e da un corpo racchiuso tra parentesi graffe, come in:

Una delle principali motivazioni del sistema dei moduli è un forte incapsulamento.

module modulename
}

Il corpo della dichiarazione del modulo può essere vuoto o contenere varie direttive del modulo, tra cui requires, exports, provides…with, uses e opens (che spiegheremo una a una). Come vedrai in seguito, la compilazione della dichiarazione del modulo crea il descrittore del modulo, il quale è memorizzato in un file chiamato module-info.class nella cartella radice del modulo. Qui introduciamo brevemente ogni direttiva del modulo. Dopo di che, presenteremo le dichiarazioni effettive del modulo.

Le parole chiave exports, module, open, opens, provides, requires, uses, with, oltre a to e transitive, che introdurremo successivamente, sono parole chiave con limitazioni. Sono parole chiave solo nelle dichiarazioni del modulo e possono essere utilizzate come identificativi in qualsiasi altro punto del codice.

requires. Una direttiva del modulo requires indica che questo modulo ne dipende da un altro. Questa relazione è definita come dipendenza del modulo. Ogni modulo deve indicarne in modo esplicito le dipendenze. Quando il modulo A requires il modulo B, si dice che il modulo A legge il modulo B e viceversa il modulo B viene letto dal modulo A. Per specificare una dipendenza su un altro modulo, utilizza requires, come in:

requires modulename;

Esiste anche una direttiva requires static per indicare che un modulo è necessario in fase di compilazione, ma è facoltativo in fase di esecuzione. Questa è nota come dipendenza facoltativa e non verrà approfondita in questa introduzione.

requires transitive—implied readability. Per specificare una dipendenza da un altro modulo e garantire che anche gli altri moduli che leggono il modulo rilevano tale dipendenza, denominata implied readability: utilizza requires transitive, come in:

requires transitive modulename;

Prendi in considerazione la seguente direttiva della dichiarazione del modulo java.desktop:

requires transitive java.xml

in questo caso, qualsiasi modulo che legge java.desktop legge anche implicitamente java.xml. Ad esempio, se un metodo del modulo java.desktop restituisce un tipo del modulo java.xml, il codice nei moduli che leggono java.desktop dipende da java.xml. Senza la direttiva requires transitive nella dichiarazione del modulo di java.desktop, tali moduli dipendenti non verranno compilati a meno che esplicitamente non leggano java.xml.

Secondo JSR 379, i moduli standard di Java SE devono garantire la leggibilità implicita in tutti i casi, come quello descritto qui. Inoltre, sebbene un modulo standard di Java SE possa dipendere da moduli non standard, non deve garantire la leggibilità implicita agli stessi. Ciò assicura che il codice, a seconda dei soli moduli standard di Java SE, sia portabile nelle implementazioni di Java SE.

exports ed exports…to. Una direttiva del modulo exports indica uno dei pacchetti del modulo i cui tipi public (e i relativi tipi public e protected nidificati) devono essere accessibili al codice in tutti gli altri moduli. Una direttiva exports…to consente di specificare in una lista separata da virgole quale codice del modulo o dei moduli può accedere al pacchetto esportato; questo è definito come un'esportazione qualificata

uses. Una direttiva del modulo uses specifica un servizio utilizzato da questo modulo, rendendo il modulo un consumer di servizi. Un servizio è un oggetto di una classe che implementa l'interfaccia o estende la classe abstract specificata nella direttiva uses.

provides…with. Una direttiva del modulo provides…with indica che un modulo fornisce un'implementazione del servizio, rendendolo un provider di servizi. La parte provides della direttiva indica un'interfaccia o una classe abstract elencata nella direttiva uses di un modulo, mentre la parte with della direttiva indica il nome della classe del provider di servizi che implements l'interfaccia o extends la classe abstract.

open, opens, e opens…to. Prima di Java 9, era possibile utilizzare la riflessione per conoscere tutti i tipi di un package e tutti i membri di un tipo, anche i relativi membri private, indipendentemente dal fatto che si desideri o meno consentire questa funzionalità. Quindi, niente è stato realmente incapsulato.

Una delle principali motivazioni del sistema dei moduli è il forte incapsulamento. Di default, un tipo in un modulo non è accessibile ad altri moduli a meno che non si tratti di un tipo pubblico e non si esporti il relativo pacchetto. Esponi solo i pacchetti che desideri esporre. Con Java 9, questo vale anche per la riflessione.

Permettere un accesso runtime-only a un pacchetto. Una direttiva modulo opens come

opens package

indica che i tipi public di un determinato pacchetto (e i relativi tipi public e protected nidificati) sono accessibili al codice in altri moduli solo in runtime. Inoltre, tutti i tipi nel pacchetto specificato (e tutti i membri dei tipi) sono accessibili tramite riflessione.

Consetire l'accesso solo runtime a un pacchetto da parte di moduli specifici. Una direttiva del modulo opens…to

opens package to comma-separated-list-of-modules

indica che i tipi public di un determinato pacchetto (e i relativi tipi public e protected nidificati) sono accessibili al codice nei moduli elencati solo in runtime. Tutti i tipi nel pacchetto specificato (e tutti i membri dei tipi) sono accessibili tramite la riflessione al codice nei moduli specificati.

Consentire l'accesso solo runtime a tutti i pacchetti in un modulo. Se tutti i pacchetti di un determinato modulo devono essere accessibili in fase di runtime e tramite riflessione a tutti gli altri moduli, puoi eseguire open sull'intero modulo, come in:

open module modulename {
   // module directives

Impostazioni predefinite della riflessione

Di default, un modulo con accesso riflettente in runtime a un pacchetto può visualizzare i tipi public del pacchetto (e i relativi tipi public e protected nidificati). Tuttavia, il codice in altri moduli può accedere a tutti i tipi nel pacchetto esposto e a tutti i membri di tali tipi, inclusi i membri private tramite setAccessible, come nelle versioni Java precedenti.

Per ulteriori informazioni su setAccessible e sulla riflessione, consulta la documentazione di Oracle.


Paul Deitel, CEO e Chief Technical Officer di Deitel & Associates, ha una laurea presso il Massachusetts Institute of Technology e 35 anni di esperienza nel settore informatico. È un Java Champion e programma in Java da oltre 22 anni. Lui e il suo coautore, Dr. Harvey M. Deitel, sono gli autori di linguaggio di programmazione che vendono di più al mondo. Paul ha tenuto corsi di programmazione su Java, Android, iOS, C#, C++, C e su Internet a clienti del settore, di governo e accademici a livello internazionale.


NOTA: questo articolo è tratto da Java Magazine settembre/ottobre 2017.

Per saperne di più

Oracle Chatbot
Disconnected