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

18

Java 9 avrà moduli in aggiunta ai pacchetti. Di solito le lingue hanno l'una o l'altra. La maggior parte dei programmatori percepiscono due termini come sinonimi. I moduli sono costruiti sopra i pacchetti, trattandoli come primitivi. Il modello composito suggerisce di trattare uniformemente i primitivi e i compositi. Altrimenti accadranno cose brutte. Ad esempio, guarda il progetto Valhalla, dove cercano di adattare 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 degli interessi). O Java deve avere sia come tributo 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

A module is a named, self-describing collection of code and data. Its code is organized as a set of packages containing types, i.e., Java classes and interfaces; its data includes resources and other kinds of static information.

JLS evita accuratamente di definire cos'è un pacchetto . Da Wikipedia :

A Java package is a technique for organizing Java classes into namespaces similar to the modules of Modula, providing modular programming in Java.

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

The term package is sometimes used instead of module (as in Dart, Go, or Java). In other implementations, this is a distinct concept; in Python a package is a collection of modules, while in the upcoming Java 9 the introduction of the new module concept (a collection of packages with enhanced access control) is planned.

    
posta user2418306 27.02.2016 - 23:10
fonte

2 risposte

18

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

Java ha sempre avuto moduli. Un metodo è un modulo, quindi è una classe e quindi è un pacchetto. Un modulo è un'unità di organizzazione in cui i dettagli interni sono nascosti e che comunica 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 di ritorno). I moduli possono essere composti da moduli di livello inferiore, ad es. le classi contengono metodi.

Ciò che manca nel core Java (pre-9) è un modulo distribuibile . Tutti i suddetti tipi di modulo non sono unità schierabili che possono essere copiati. Java ha un artefatto deployable chiamato file JAR, ma questi non sono moduli perché non hanno incapsulamento o contratto: a runtime i file JAR scompaiono, tutti fondendosi insieme in un singolo "classpath".

OSGi ha affrontato la mancanza di moduli schierabili nel 1998 con il concetto di "pacchetto". Questi sono file JAR fisici 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 del tutto 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". Questo non significa che metodi, classi e pacchetti smettono di essere moduli! Un "modulo" J9 è solo un'altra istanziazione del modulo concetto . Come i bundle OSGi, i moduli J9 sono fatti di pacchetti e sono artefatti fisici (di solito i file JAR di nuovo) che possono essere copiati. Il sistema di runtime li comprende e li reifica.

Riepilogo: sì I moduli J9 e i pacchetti sono nozioni semanticamente separate. Ovviamente Java deve mantenere il suo concetto di pacchetto esistente per la compatibilità all'indietro. Si noti che la parola "pacchetto" è usata in modo molto 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 a pacchetti in RPM rispetto a quelli di Java.

    
risposta data 23.03.2016 - 01:42
fonte
10

Permettetemi di azzardare una risposta, anche se molte di queste potrebbero essere delle ipotesi / spaccare i capelli / fare una canzoncina, ecc.

Sono la stessa cosa? Bene, si e no

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

Packages as a modular solution

Packages attempt to add a level of abstraction to the Java programming landscape. They provide facilities for unique coding namespaces and configuration contexts. Sadly, though, package conventions are easily circumvented, frequently leading to an environment of dangerous compile-time couplings.

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

Bene, qual è la differenza?

Tuttavia, la differenza è nei metadati all'interno di ciascuno di essi. I manifesti di Java package , 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 (nuovamente articolo JavaWorld) :

Aren't JAR files modular enough?

JAR files and the deployment environment in which they operate greatly improve on the many legacy deployment conventions otherwise available. But JAR files have no intrinsic uniqueness, apart from a rarely used version number, which is hidden in a .jar manifest. The JAR file and the optional manifest are not used as modularity conventions within the Java runtime environment. So the package names of classes in the file and their participation in a classpath are the only parts of the JAR structure that lend modularity to the runtime environment.

Una sfuriata su altri linguaggi / ambienti, ecc.

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

Dependency management:

Maven encourages the use of a central repository of JARs and other dependencies. Maven comes with a mechanism that your project's clients can use to download any JARs required for building your project from a central JAR repository much like Perl's CPAN. This allows users of Maven to reuse JARs across projects and encourages communication between projects to ensure that backward compatibility issues are dealt with.

Ora parliamo del futuro come se fossi stato lì

Poiché quella pagina menzionata, altri linguaggi (come Perl), hanno repository di pacchetti (come CPAN ). Questa è una tendenza in aumento (dico perché ne ho voglia, senza alcuna prova empatica), nell'ultimo decennio circa. Strumenti come gemme di Ruby, Python PyPi e Gestore pacchetti nodo ( npm ) si baserà su questo per fornire un modo coerente di configurare un ambiente (sviluppo, build, test o runtime, ecc.) con il giusto materiale (pacchetti, moduli, gemme, gizmo, ecc.). Un'idea (credo) era " preso in prestito " dai sistemi di distribuzione Linux® come Debian apt , RedHat's rpm , ecc. (Anche se, ovviamente, si è evoluta almeno una una generazione, e ha reso queste cose più belle.)

Moduli Java , anche se non aggiungono necessariamente qualcosa che non puoi già fare, rendono gli strumenti per dipendenze / gestione dei pacchetti e ambienti di compilazione automatizzati tutti MUCH più facili. Se questo rende i moduli "migliori", declino di dire. : P

    
risposta data 28.02.2016 - 13:48
fonte

Leggi altre domande sui tag