Vraag Eclipse Java-projectmaporganisatie


Ik kom naar Java en Eclipse vanaf een C # / Visual Studio-achtergrond. In het laatste geval zou ik normaal gesproken een oplossing organiseren zoals:

\ MyProjects \ MyApp \ MyAppsUtilities \ LowerLevelStuff

waar MyApp een project zou bevatten om een ​​.exe te bouwen, zou MyAppsUtilities een assembly-DLL maken die wordt aangeroepen door de .exe, en LowerLevelStuff zou waarschijnlijk een assembly bouwen met klassen die worden gebruikt door de DLL van het hogere niveau.

In Eclipse (Ganymede, maar kan ervan overtuigd worden om over te schakelen naar Galileo) heb ik:

\ MyProjects \ workspace \ MyApp

Wanneer ik mijn eerste project maak. Er is een optie om bron- en buildbestanden in dezelfde map te plaatsen, maar ik heb .java-bestanden gemaakt op een pad dat een afspiegeling is van mijn pakkethiërarchie:

\ MyProjects \ workspace \ MyApp \ src \ com \ mijnbedrijf \ myapp \ MyApp.java

Mijn vraag is deze: wanneer ik subprojecten maak (is dat de juiste Java / Eclipse-term?) Voor .jar-bestanden die analoog zijn aan de bovenstaande DLL's van MyAppsUtilities en LowerLevelStuff in .NET, kan (zou) ik de mappen op een gelijkwaardige manier indelen? bijv .:

\ MyProjects \ workspace \ MyApp \ src \ com \ mijnbedrijf \ MyApp \ myapputilities \ MyAppsUtilities.java

Wat is de standaard / juiste manier om dit soort dingen te ordenen en hoe wordt dit specifiek uitgevoerd in de IDE?


25
2017-10-02 15:33


oorsprong


antwoorden:


Beschouw Java-broncodepakketten als één grote hiërarchische naamruimte. Commerciële toepassingen leven meestal onder 'com.mycompany.myapp'(de website voor deze toepassing kan'http://myapp.mycompany.com'hoewel dit uiteraard niet altijd het geval is).

Hoe u dingen onder uw myapp-pakket organiseert, hangt grotendeels van u af. Het onderscheid dat u maakt voor C # tussen uitvoerbare (.exe), DLL's en klassen op laag niveau bestaat niet in dezelfde vorm in Java. Alle Java-broncode is gecompileerd tot .class-bestanden (de inhoud hiervan wordt 'bytecode' genoemd) die op veel platforms kan worden uitgevoerd door een Java Virtual Machine (JVM). Er is dus geen inherent onderscheid in klassen op hoog niveau / laag niveau, tenzij u dergelijke niveaus toewijst via uw verpakking. Een veel voorkomende manier van verpakken is:

  • com.mycompany.myapp: hoofdklasse; MyApp (met een hoofdmethode)
  • com.mycompany.myapp.model: domeinmodelklassen; Klant, bestelling, etc.
  • com.mycompany.myapp.ui: gebruikersinterface (presentatie of weergave) code
  • com.mycompany.myapp.service: services binnen uw applicatie, d.w.z. 'business logic'
  • com.mycompany.myapp.util: helperklassen die op verschillende plaatsen worden gebruikt

dit suggereert een zelfstandige Java-app, het kan anders zijn als het een webapp is die een van de vele frameworks gebruikt.

Deze pakketten komen overeen met een maphiërarchie in uw project. Wanneer u Eclipse gebruikt, wordt de hoofdmap van een dergelijke hiërarchie een 'brondirectory' genoemd. Een project kan meerdere bronmappen definiëren, meestal een 'hoofd'- en een' test'-brondirectory.

Voorbeeld van bestanden in uw project:

src/test/java/com/acme/foo/BarTest.java
src/main/java/com/acme/foo/Bar.java
lib/utilities_1_0.jar

En binnen utilities_1_0.jar:

com/acme/foo/BarUtils.class

BarUtils.class dit is een gecompileerde Java-klasse, dus in platformonafhankelijke bytecode-vorm die kan worden uitgevoerd op elke JVM. Gewoonlijk bevatten jarfiles alleen de gecompileerde klassen, hoewel je soms een versie van de pot kunt downloaden die ook de bronbestanden (.java) bevat. Dit is handig als u de originele broncode van een jar-bestand dat u gebruikt wilt kunnen lezen.

In het bovenstaande voorbeeld zijn Bar, BarTest en BarUtils allemaal in hetzelfde pakket com.acme.foo, maar bevinden ze zich fysiek op verschillende locaties op uw harde schijf.

Klassen die zich direct in een bronmap bevinden, bevinden zich in het 'standaardpakket', het is meestal geen goed idee om de klassen daar te houden omdat het niet duidelijk is tot welk bedrijf en welke toepassing de klas behoort en u naamconflicten kunt krijgen als een jar-bestand u toevoegt aan uw classpath bevat een klasse met dezelfde naam in het standaardpakket.

Als u deze toepassing nu implementeert, wordt deze normaal gesproken gecompileerd tot .class-bestanden en gebundeld in .jar (wat eigenlijk een mooie naam is voor een ZIP-bestand plus enkele manifestinformatie). Een .jar maken is niet nodig om de applicatie uit te voeren, maar handig bij het distribueren / distribueren van uw applicatie. Met behulp van de manifestinformatie kunt u een .jar-bestand 'uitvoerbaar' maken, zodat een gebruiker het gemakkelijk kan uitvoeren, zie [a].

Meestal zult u ook verschillende bibliotheken gebruiken, dat wil zeggen bestaande .jar-bestanden die u van internet hebt verkregen. Zeer veelvoorkomende voorbeelden zijn log4j (een logging-framework) of JDBC-bibliotheken voor toegang tot een database, enz. U kunt ook uw eigen submodules hebben die in afzonderlijke jarfiles worden gebruikt (zoals 'utilities_1_0.jar' hierboven). Hoe dingen verdeeld zijn over jarfiles is een distributie / distributie kwestie, ze delen nog steeds allemaal de universele naamruimte voor de Java-broncode. In feite kun je alle jarfiles unzippen en de inhoud in één grote directorystructuur plaatsen als je dat wilde (maar dat doe je meestal niet).

Bij het uitvoeren van een Java-toepassing die gebruikmaakt / bestaat uit meerdere bibliotheken, kom je tegen wat gewoonlijk wordt aangeduid als 'Classpath hell'. Een van de grootste nadelen van Java zoals we dat kennen. (opmerking: hulp is zogenaamd onderweg). Om een ​​Java-toepassing op de opdrachtregel (dus niet van Eclipse) uit te voeren, moet u elke .jar-bestandslocatie in het klassenpad opgeven. Wanneer u een van de vele frameworks van Java (Maven, Spring, OSGi, Gradle) gebruikt, is er gewoonlijk enige vorm van ondersteuning om deze pijn te verlichten. Als u een webtoepassing bouwt, moet u zich in het algemeen houden aan de conventies voor het aanbrengen van lagen / implementaties om het ding eenvoudig te kunnen implementeren in de webcontainer van uw keuze (Tomcat, Jetty, Glassfish).

Ik hoop dat dit een algemeen inzicht geeft in hoe de dingen op Java werken!

[a] Om een ​​uitvoerbare pot van de MyApp-toepassing te maken, hebt u een JDK op uw pad nodig. Gebruik vervolgens de volgende opdrachtregel in uw compilatie (bin of doel) map:

jar cvfe myapp.jar com.mycompany.myapp.MyApp com\mycompany\myapp

U kunt het vervolgens uitvoeren vanaf de opdrachtregel met:

java -jar myapp.jar

of door te dubbelklikken op het jar-bestand. Merk op dat u de Java-console in dat geval niet zult zien, dus dit is alleen handig voor toepassingen die hun eigen GUI hebben (zoals een Swing-app) of die op de achtergrond kunnen draaien (zoals een socketserver).


51
2017-10-02 16:53



Maven heeft een goed doordacht standaard directory lay-out. Zelfs als je Maven niet direct gebruikt, kun je dit zien als een defacto-standaard. Maven 'multi-module'-projecten zijn een goede analogie met de .net-lay-out voor meerdere assembly's die u hebt beschreven.


7
2017-10-02 16:10



Er zijn twee dingen die je moet verduidelijken voordat deze vraag kan worden beantwoord:

  1. Welke broncode-repository zal je gebruiken?
  2. Welk build-systeem zal je gebruiken om automatisch artefacten te bouwen buiten Eclipse?

De antwoorden zullen uw opties sterk beïnvloeden.

We hebben gekozen voor 'één Eclipse-project pr-onderdeel' dat een bibliotheek of een voltooide uitvoerbare / uitvoerbare pot kan zijn. Hierdoor is het eenvoudig om met Hudson te automatiseren. Ons gebruik van CVS is ook eenvoudiger, omdat afzonderlijke projecten niet meerdere verantwoordelijkheden hebben.

Merk op dat elk project meerdere bronmappen kan bevatten die bijvoorbeeld test code uit de configuratie van de Java-bron. Dat is niet zo belangrijk als het vereenvoudigen van uw structuur.


2
2017-10-02 17:41



Meestal zou u gerelateerde / subprojecten maken als verschillende projecten in Eclipse.


1
2017-10-02 15:36