Perché pacchetti e moduli sono concetti separati in Java 9?


21

Java 9 avrà moduli oltre ai pacchetti. Di solito le lingue hanno l'una o l'altra. E la maggior parte dei programmatori percepisce due termini come sinonimi. I moduli sono costruiti sopra i pacchetti, trattandoli come primitivi. Il modello composito suggerisce di trattare in modo uniforme primitivi e compositi. Altrimenti succederanno cose brutte. Ad esempio, guarda il progetto Valhalla, in cui cercano di aggiornare il supertipo comune per i tipi primitivi (valore) e di riferimento.

I moduli e i pacchetti rappresentano nozioni semanticamente separate? Significa che è ragionevole avere entrambi per qualsiasi lingua (separazione delle preoccupazioni). O Java deve avere entrambi come omaggio alla retrocompatibilità?

Perché introdurre un nuovo concetto invece di aumentare quello esistente?


JSR 376 : "Sistema modulo piattaforma Java" implementato all'interno del progetto Jigsaw .

Secondo SOTMS

Un modulo è una raccolta denominata e auto-descrittiva di codice e dati. Il suo codice è organizzato come un insieme di pacchetti contenenti tipi, ovvero classi e interfacce Java; i suoi dati includono risorse e altri tipi di informazioni statiche.

JLS evita accuratamente di definire cosa sia un pacchetto . Da Wikipedia :

Un pacchetto Java è una tecnica per organizzare le classi Java in spazi dei nomi simili ai moduli di Modula, fornendo una programmazione modulare in Java.

So che citare Wikipedia è una cattiva pratica, ma riflette una comprensione comune. Dalla voce sulla programmazione modulare:

Il termine pacchetto viene talvolta utilizzato al posto del modulo (come in Dart, Go o Java). In altre implementazioni, questo è un concetto distinto; in Python un pacchetto è una raccolta di moduli, mentre nell'imminente Java 9 è prevista l'introduzione del nuovo concetto di modulo (una raccolta di pacchetti con controllo di accesso avanzato).


3
Penso che tu stia facendo molte domande tutte insieme qui? 1) I moduli e i pacchetti sono la stessa idea semantica? 2) (se non 1), i jigsawmoduli in stile sono solo un miglioramento tecnico rispetto ai pacchetti? 3) (se non 1 e se 2), Java semplicemente (o apparentemente) mantiene entrambi i concetti per la retrocompatibilità. Alcune di queste domande sono rispondenti, altre sono principalmente orientate all'opinione pubblica. Penso che una modifica che semplifichi i chiarimenti richiesti sia qui.
Tersosauro,

1
@Tersosauros Hai classificato "alcune" domande come fuori tema, ma non hai etichettato quale sia quale. Lo vedo come una sola domanda (1). Altro verrà risolto automaticamente. La compatibilità con le versioni precedenti di Java non è una domanda. Quindi, o java ha introdotto moduli per correggere i difetti di progettazione dei pacchetti o due nozioni sono preoccupazioni veramente separate. E la confusione è dovuta alla cattiva denominazione.
user2418306,

1
Voglio chiarire la questione. Ma devo capire quale parte di esso pensi sia senza risposta. Quando penso che ci sia solo una parte.
user2418306,

Ah, capisco la confusione. Penso che la domanda n. 1 sia rispondente (quella risposta è "Sì, ma no" - che è dove arriva il n. 3). Sono d'accordo su # 3, ovviamente Java non cambierà ciò che una parola chiave come la lingua packageè / fa / significa, né cambierà (diciamocelo, piuttosto orribile) i sistemi di percorsi di classe in JRE. Domanda n. 2 Penso che sia principalmente orientato all'opinione (è responsabile , ma la mia risposta e quella di qualcun altro potrebbero essere diverse e nessuno di noi avrebbe necessariamente torto).
Tersosauros,

1
Prova a porre una domanda chiara in anticipo, quindi fornisci il materiale di supporto.
Jay Elston

Risposte:


22

Il concetto di un modulo è diverso dall'istanza di quel concetto.

Java ha sempre avuto moduli. Un metodo è un modulo, quindi è una classe e un pacchetto. Un modulo è un'unità organizzativa in cui i dettagli interni sono nascosti e che comunicano con altri moduli tramite contratti concordati. Ad esempio, un metodo è un modulo perché ha interni nascosti (il codice e le variabili locali) e un contratto (i parametri e il tipo restituito). I moduli possono essere composti da moduli di livello inferiore, ad esempio le classi contengono metodi.

Ciò che manca nel core Java (pre-9) è un modulo distribuibile . Tutti i suddetti tipi di modulo non sono unità dispiegabili che possono essere copiate. Java ha un artefatto distribuibile chiamato file JAR, ma questi non sono moduli perché non hanno incapsulamento o contratto: in fase di esecuzione i file JAR scompaiono, tutti uniti in un unico "percorso di classe".

OSGi ha affrontato la mancanza di moduli implementabili nel 1998 con il concetto di "bundle". Questi sono file JAR fisicamente e contengono pacchetti, ma OSGi definisce metadati aggiuntivi insieme a un sistema di runtime per supportare l'incapsulamento e i contratti a quel livello.

Java 9 affronta la mancanza di moduli distribuibili in modo simile a OSGi. Probabilmente questo era completamente inutile perché OSGi esiste e funziona, ma questa è una discussione completamente diversa ...

Sfortunatamente Java 9 confonde le acque nominando il nuovo concetto di modulo solo un "modulo". Ciò non significa che metodi, classi e pacchetti smettano di essere moduli! Un "modulo" J9 è solo un'altra istanza del concetto di modulo . Come i bundle OSGi, i moduli J9 sono fatti di pacchetti e sono artefatti fisici (di solito file JAR di nuovo) che possono essere copiati. Il sistema di runtime li comprende e li reifica.

Riepilogo: sì I moduli e i pacchetti J9 sono nozioni semanticamente separate. Ovviamente Java deve conservare il suo concetto di pacchetto esistente per compatibilità con le versioni precedenti. Si noti che la parola "pacchetto" è utilizzata in modo abbastanza diverso in Java rispetto ad altre lingue o in sistemi di gestione dei pacchetti come RPM. I nuovi moduli J9 (e bundle OSGi) sono molto più simili ai pacchetti in RPM di quanto non lo siano mai stati i pacchetti Java.


Il pacchetto non soddisfa la tua definizione di modulo. A causa dell'incapsulamento debole e della mancanza di mezzi per aggregare altri pacchetti e affinare la loro visibilità. Le classi possono contenere classi o campi nidificati. I metodi possono contenere chiusure o chiamare altri metodi. I pacchetti non possono "comunicare" con altri pacchetti.
user2418306

Non sono d'accordo. I pacchetti hanno informazioni nascoste (tipi di accesso predefiniti, metodi e campi, aka pacchetto-privato). I pacchetti certamente "comunicano" perché il codice all'interno di un pacchetto può invocare il codice in altri pacchetti. Questo viene fatto contro un contratto, vale a dire i tipi e i metodi pubblici dell'altro pacchetto.
Neil Bartlett,

Si noti che la capacità di aggregare artefatti modulari allo stesso livello (ad es. Metodi contenenti chiusure, classi contenenti classi nidificate) NON fa parte della mia definizione di modulo. Se si considera che questa è una parte necessaria della definizione del modulo, anche i "moduli Java 9" non sono moduli.
Neil Bartlett,

Non nego che i pacchetti abbiano informazioni nascoste . Ho detto che non è sufficiente. importpuò accoppiare pacchetti. Ma non c'è modo di strutturare i pacchetti come cittadini di prima classe. Tali carenze (e limitazioni di OSGi) sono descritte in JSR 376.
user2418306

Puoi spiegare perché anche i moduli Java 9 non sono moduli ?
user2418306

10

Consentitemi di rischiare una risposta, anche se gran parte può essere ipotesi / scissione di peli / sfilacciamento, ecc.

Sono la stessa cosa? Bene, e no

Da questo articolo di JavaWorld su "Modularità in Java 9" :

Pacchetti come soluzione modulare

I pacchetti tentano di aggiungere un livello di astrazione al panorama della programmazione Java. Forniscono servizi per spazi dei nomi e contesti di configurazione univoci. Purtroppo, tuttavia, le convenzioni sui pacchetti vengono facilmente aggirate, portando spesso a un ambiente di pericolosi accoppiamenti in fase di compilazione.

Come suggerito da @ user2418306 (OP) , "i moduli sono pacchetti fatti correttamente " . Moduli e pacchetti in Java (ovviamente da Java 9, ovviamente) sono (come chiede OP) semanticamente la stessa cosa. Cioè, sono raccolte di bytecode JVM precompilate, con altri metadati - essenzialmente , sono librerie .

Bene, qual è la differenza?

Tuttavia, la differenza sta nei metadati all'interno di ciascuno di essi. I packagemanifesti Java o manifesti JAR non sono spesso gestiti dagli sviluppatori di librerie, né forniscono alcun contratto sicuro su ciò che fornisce il pacchetto JAR /. Come spiegato qui (di nuovo l'articolo di JavaWorld) :

I file JAR non sono abbastanza modulari?

I file JAR e l'ambiente di distribuzione in cui operano migliorano notevolmente le numerose convenzioni di distribuzione legacy altrimenti disponibili. Ma i file JAR non hanno unicità intrinseca, a parte un numero di versione usato raramente, che è nascosto in un manifest .jar. Il file JAR e il manifest facoltativo non vengono utilizzati come convenzioni di modularità all'interno dell'ambiente di runtime Java. Quindi i nomi dei pacchetti delle classi nel file e la loro partecipazione in un percorso di classe sono le uniche parti della struttura JAR che conferiscono modularità all'ambiente di runtime.


Un'ondata di altre lingue / ambienti, ecc

Un'altra area discussa in quell'articolo sono i sistemi come Maven , che gestiscono le dipendenze per te come parte del processo di compilazione. Da questa pagina sul sito Apache Maven :

Gestione delle dipendenze:

Maven incoraggia l'uso di un repository centrale di JAR e altre dipendenze. Maven viene fornito con un meccanismo che i clienti del tuo progetto possono utilizzare per scaricare qualsiasi JAR necessario per costruire il tuo progetto da un repository JAR centrale, proprio come il CPAN di Perl. Ciò consente agli utenti di Maven di riutilizzare i JAR in tutti i progetti e incoraggia la comunicazione tra i progetti per garantire che vengano affrontati i problemi di compatibilità con le versioni precedenti.

Ora per parlare del futuro come se fossi stato lì

Come indicato nella pagina , altre lingue (come Perl) hanno repository di pacchetti (come CPAN ). Questa è una tendenza crescente (dico perché ne ho voglia, senza alcuna prova enfatica), nell'ultimo decennio circa. Strumenti come gemme di Ruby , PyPi di Python e Node Package Manager ( npm) si basano su questo per fornire un modo coerente di configurare un ambiente (sviluppo, build, test o runtime, ecc.) Con le cose giuste (pacchetti, moduli, gemme, gizmo, ecc.). Un'idea (credo) è stata " presa in prestito " da sistemi di distribuzione Linux® come apt di Debian , RedHatrpm, ecc. (Anche se, ovviamente, si è evoluta almeno una generazione e ha reso tutte queste cose più belle.)


I moduli Java , sebbene non aggiungano necessariamente nulla che non si possa già fare, rendono gli strumenti per le dipendenze / la gestione dei pacchetti e gli ambienti di compilazione automatizzati MOLTO più facili. Se ciò renda i moduli "migliori", mi rifiuto di dirlo. : P


1
L'articolo ha solo 1 anno e tuttavia è già obsoleto. Indica come il versioning sia una caratteristica fondamentale di un modulo. I moduli puzzle non avranno informazioni sulla versione. Nulla nel regno della gestione delle dipendenze cambierà per l'utente finale. Per gli strumenti di costruzione, le cose diventeranno molto più difficili. Come hanno bisogno di sostenere realtà parallele di classpathe modulepath. E saltare attraverso i cerchi per supportare i test unitari. Premettere che due concetti sono equivalenti perché rappresentano la raccolta di cose più i metadati è troppo audace per me accettare. Inoltre a metà strada hai improvvisamente sostituito il vaso con il pacchetto.
user2418306,

Non ho detto " due concetti sono equivalenti ", ho detto che sono "semanticamente la stessa cosa" - che è ciò di cui hai chiesto. Inoltre, hai modificato la domanda da quando ho risposto per menzionare in modo specifico JSR-376 , al contrario del puzzle che è quello che è stato detto in precedenza: - /
Tersosauros,

Il puzzle comprende (strumenti) JSR-376. La domanda si collega ancora ad entrambi, quindi non è stato fatto alcun danno. Dizionario definisce l'equivalenza come la qualità o lo stato di avere lo stesso significato. E semanticamente - per quanto riguarda il significato. Mi dispiace ma sei pedante per i dettagli sbagliati qui. Hai detto che sono equivalenti. Ma non hai fornito alcun ragionamento. Invece fai riferimento all'articolo che spiega come i pacchetti e i barattoli non siano moduli. Ma i moduli imminenti non riescono ad essere anche moduli dall'articolo. Rivendicare l'equivalenza e quindi fornire la differenza tra il 2 (3) è auto-contraddittorio.
user2418306,

La risposta alla domanda non può essere sì e no. Due concetti semanticamente equivalenti o no. Per favore, non lobotomizzare i miei commenti e tornare alla domanda originale. Una lingua ha bisogno di entrambi i concetti o si tratta di un problema specifico dell'eredità java? Se hai bisogno di chiarimenti, sono felice di aiutarti.
user2418306
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.