Package import-Klausel

ocsme

Top Contributor
Guten Tag,

zum Glück komme ich über die Anfänger Themen hier nicht raus 🙁
Diese Packages machen mir noch gänzlich Graue Haare 🙁
Bestimmt ein nettes und einfaches Thema aber ich bekomme es nicht ganz hin.

Wo liegt mein Problem
In Eclipse habe ich 2 Projekte erstellt Prog1 und Prog2.
In Prog1 habe ich Source Folder wie z. B. uebungen, sonstiges, alda, pearson und in Prog2 collections, inputOutput, uebungen, generics, javaFX
nun bräuchte ich in Prog1 unter dem Ordner pearson im package 44 etwas aus Prog2.
Muss ich nun wirklich das Projekt Prog2 in Prog1 hinzufügen über:
Project-->Properties-->Java Build Path-->Projects-->Add Project
Ich dachte es würde auch mit dem qualifizierten Namen funktionieren.
Wenn ich nun aber im package 44 eine import Klausel anhänge mit Prog2.uebung4.verschlüsselung.*; sagt er mir "The import Prog2 cannot be resolved"
Geht das so überhaupt?
Wenn NEIN dann verstehe ich nicht wie man mehrere packages aus verschiedenen Projekten und Source Folder in einer jar-Datei zusammen fügen kann?

Ich hoffe man kann meine Frage verstehen.
Danke im voraus 🙂

LG
 
Das Projekt spielt für Java überhaupt keine Rolle. Du hast einfach nur Klassen, die in Paketen liegen. Gesucht werden die Klassen im Classpath. Wenn Du in der IDE eine Abhängigkeit einfügst, dann sorgt diese dafür, dass der Classpath entsprechend angepasst wird (in der Regel wird das Jar in den Classpath eingefügt, das von dem jeweiligen Projekt erzeugt wird). Danach kannst Du die Klassen genauso importieren, als wären sie direkt Teil des Projekts.

Sprich: füg die Abhängigkeit Deinem Projekt hinzu und lass beim Import den Projektnamen einfach weg.
 
Noch etwas spezifischer für Eclipse: Wenn du eine Projektabhängigkeit zu Projekt B im Build Path deines Projektes A hinzufügst, dann sorgt das dafür, dass der classpath von Run Configurations der Klassen in A den Output Folder von Projekt B als Classpath root enthält (bzw. die Output Folder, wenn du mehrere Output Folder konfiguriert hast).
Zur Designzeit hast du ja erstmal nur .class Dateien in Ordnern (außer natürlich bei Library Dependencies, für die du schon .jar Dateien hast).
 
Danke für die Antwort.

Kann ich also wenn ich aus dem ganzen ein großes Projekt machen wollt, was hier natürlich keinen Sinn macht doch das mal außer acht, ein neuen Ordner erstellen wo ich Prog1 und Prog2 rein packe ein .jar Projekt draus machen?
In dem man die Meta-Datei ändere mit dem Classpath (keine Ahnung wie der Class-Path dann aussehen muss, mit . getrennt oder / doch dann frage ich mich was machen Windows Nutzer?)

Code:
Manifest-Version: 1.0
Class-Path: .Pro1.uebung1
Main-Class: MainKlasse

Nochmals Sry für die Triviale Frage hab das ganze auch nachgelesen doch so richtig schöne Erklärungen dazu habe ich keine gefunden 🙁

LG
 
Ich hab das Prog2 Projekt von mir über Eclipse mal gejart 😀
Nun habe ich in der Datei .classpath folgenden Eintrag:
Code:
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/Prog1"/>
Erkennt das Projekt mit einem solchen Eintrag wo er noch die .class Dateien zu suchen hat?
Sprich wenn ich ein größeres Projekt aus mehreren Projekte in eines Packen möchte, packe ich jedes Projekt in eine .jar Datei und diese ganzen .jar Dateien dann später in eine .jar Datei? Denn Eclipse hat ja wenn man den Java Build Path anpasst /Prog1 Projekt z. B. in Prog2 Projekt "eingehängt" den Path in dieser Datei.

Geht das so? oder liege ich wieder Falsch 😀

LG
 
Sprich wenn ich ein größeres Projekt aus mehreren Projekte in eines Packen möchte, packe ich jedes Projekt in eine .jar Datei und diese ganzen .jar Dateien dann später in eine .jar Datei?
Das kann man machen (habe ich persönlich noch nie gemacht). Für Eclipse siehe z. B. https://stackoverflow.com/questions...r-with-external-libraries-included-in-eclipse

Statt eines sog. Uber-Jars kann man die Jars separat halten. Dann fügt man im Manifest entsprechende Class-Path-Einträge hinzu und gut ists. Das sollte die IDE automatisch machen, wenn man eine Distribution erstellt.

Wenn man das per Hand machen würde, dann würde man sich z. B. einen Distributions-Ordner anlegen, nennen wir ihn mal dist, dort hätte man dann folgende Struktur:
Code:
dist\haupt-projekt.jar
dist\libs\subprojekt1.jar
dist\libs\subprojekt2.jar
dist\libs\bibliothek1.jar
usw.
Im Manifest des Hauptprojekts (in haupt-projekt gepackt) stünde dann etwas wie
Code:
Class-Path: libs/subprojekt1.jar libs/subprojekt2.jar libs/bibliothek1.jar usw.
 
Bevor ich das allerdings per Hand (oder mit IDE) machen würde, würde ich einfach ein Build-Tool wie Maven oder Gradle nutzen, das kümmert sich um das ganze Dependency-Management (neben einigen anderen Vorteilen.)
 
@mrBrown da hast Du natürlich völlig recht. Trotzdem schadet es nicht, zu wissen, was hinter den Kulissen passieren muss.

@ocsme Mal ein Beispiel ganz ohne IDE.

Code:
mkdir greeter
cd greeter
mkdir src
mkdir src/greeter
mkdir build
mkdir dist

Jetzt erstellst Du unter src/greeter eine Datei Greeter.java:
Java:
package greeter;

public class Greeter {
    public void sayHello(String name) {
        System.out.println("Hello " + name);
    }
}

Übersetzen:
Code:
javac -d build src/greeter/Greeter.java

Jetzt findet man unter build die Package-Struktur inkl. des .class-Files. Daraus erstellen wir ein JAR dist/greeter.jar:
Code:
jar -cvf dist/greeter.jar -C build .
(Achtung: da steht ein Punkt am Ende)

Als nächstes legen wir ein zweites Projekt an (analog oben):
Code:
# Projekt-Root greeter verlassen
cd ..
mkdir launcher
cd launcher
mkdir src
mkdir src/launcher
mkdir build
mkdir dist
mkdir dist/libs

Dann brauchen wir eine Java-Klasse, sagen wir mal unter src/launcher/App.java
Java:
package launcher;

import greeter.Greeter;

public class App {
    public static void main(String[] args) {
        Greeter greeter = new Greeter();

        if (args.length == 0) {
            System.err.println("Fehler: kein Name angegeben");
            System.exit(1);
        }

        greeter.sayHello(args[0]);
    }
}

Übersetzen (diesmal etwas komplizierter, weil nun die Klassen aus dem greeter-Projekt in den Classpath aufgenommen werden müssen, damit der Compiler diese findet):
Code:
# Möglichkeit 1: Klassen aus Jar verwenden
javac -d build -cp ../greeter/dist/greeter.jar src/launcher/App.java
# Möglichkeit 2: Klassen aus dem build-Verzeichnis verwenden
javac -d build -cp ../greeter/build src/launcher/App.java

In build findet sich nun die Paketstruktur inkl. der Klasse Launcher. Jetzt wollen wir ein executable Jar daraus machen. Dafür brauchen wir ein Manifest, das wir einfach mal als Manifest.txt direkt im Projektverzeichnis anlegen:
Code:
Main-Class: launcher.App
Class-Path: libs/greeter.jar
Jetzt das Jar bauen:
Code:
jar -cvfm dist/launcher.jar Manifest.txt -C build .
(Achtung wieder ein Punkt am Ende)
Abschließend muss man noch die greeter.jar nach dist/libs kopieren.

Jetzt kann man die Anwendung z. B. per
Code:
java -jar dist/launcher.jar ocsme
aufrufen.

Nachtrag: ausgeliefert würde dann der Inhalt des dist-Verzeichnisses, also
Code:
launcher.jar
libs/greeter.jar
 
Das ganze werde ich morgen ausprobieren.
Danke für die große Mühe 🙂

Eine aller letzte kleine Frage habe ich heute Abend noch "denke ich werde sie erst morgen lesen!" muss Schlafen gehen mir fallen die Augen zu 😀
Wo sehe ich den in Eclipse den Class-Path? Ich nutze Ubuntu deswegen musste ich damit bis jetzt noch so gut wie nichts tun 😛

LG
 
Wo sehe ich den in Eclipse den Class-Path?
Ich weiß gar nicht, ob man sich den explizit anzeigen lassen kann (in Eclipse sowieso nicht, weil ich die IDE nicht verwende). Im Classpath befindet sich aber nichts anderes als die Klassen des Projekts und alle Abhängigkeiten. Dabei unterscheidet die IDE normalerweise noch zwischen dem Classpath, der zur Übersetzungszeit und dem, der zur Laufzeit verwendet wird.

Warum? Weil ein JDBC-Treiber nur zur Laufzeit, nicht aber zur Übersetzungszeit benötigt wird.

Außerdem kann es noch Unterschiede zwischen verschiedenen "Profilen" geben. Beispielsweise: Test und Nicht-Test.
 

Zurück
Oben