Compiler-Fehler Klasse in einem Package wird nicht gefunden bzw. akzeptiert

HansD

Mitglied
Wir haben bisher die Lösung nicht gefunden.

Soweit ich bisher weiß, kann ich Klassen eines Package auch pauschal importieren, und ich habe es übungshalber wie folgt versucht:

Java:
import hans.daten.*;

public class Programm2
{
  public static void main(String[] args)
  {
    Eins obj1 = new Eins();
    Zwei obj2 = new Zwei();

    obj1.hallo();
    obj2.hallo();
  }
}

Die Klassen Eins und Zwei gehören zum Package "hans.daten", und beispielsweise Zwei sieht so aus:

Java:
package hans.daten;

public class Zwei
{
  public void hallo()
  {
    System.out.println("2");
  }
}

Eins auch nicht viel anders:

Java:
package hans.daten;

public class Eins
{
  private String outp;

  public void Eins()
  {
      this.outp = "In Eins";
  }

  public void hallo()
  {
    System.out.println(this.outp);
  }
}

Ich habe wie folgt kompiliert:

$ javac -d . {Eins,Zwei}java
$ javac Programm2.java

Die Verzeichnistruktur ist wie folgt:

Bash:
.
├── hans
│   └── daten
│       ├── Eins.class
│       ├── Programm.class
│       └── Zwei.class
├── Eins.java
├── Programm2.java
├── Programm.java
└── Zwei.java

Importiere ich in Programm2.java explizit wie folgt funktioniert es.
Java:
import hans.daten.Eins;
import hans.daten.Zwei;

Aber nicht, wenn ich pauschal importiere:

Java:
import hans.daten.*;

Dann geschieht Folgendes:

Bash:
-rw-rw-r-- 1 230 Mai 16 14:47 Programm2.java
hans@bodhi-desktop:~/Java/java1/06_tag$ javac Programm2.java
Programm2.java:8: error: cannot access Eins
    Eins obj1 = new Eins();
    ^
  bad source file: ./Eins.java
    file does not contain class Eins
    Please remove or make sure it appears in the correct subdirectory of the sourcepath.
1 error
hans@bodhi-desktop:~/Java/java1/06_tag$

Warum?
 
Die Antwort gibt Dir der Compiler:
Das habe ich selbstverständlich gelesen. Der Unterordner von "Programm2.java" aus gesehen ist "hans/daten" und genau das habe ich auch beim Import in der Datei "Programm2.java" angegeben als "import hans.daten.*". Ich sehe keinen Unterschied.

PS: Wenn diese Pfadangabe falsch wäre, dann müsste, scheint mir, "import hans.daten.Eins" genauso falsch sein; aber das wird klaglos akzeptiert.
 
Du hast die Struktur doch aufgezeigt:
Code:
├── hans
│   └── daten
│       ├── Eins.class
│       ├── Programm.class
│       └── Zwei.class
├── Eins.java
├── Programm2.java
├── Programm.java
└── Zwei.java

Somit sind die Dateien nicht an dem von dir beschriebenen Ort. Du brauchst eine Verzeichnisstruktur, die der Package Struktur entspricht.

Und dann musst Du entweder angeben, wo das Source Verzeichnis ist oder Du musst Dich in dem Source Verzeichnis befinden. Und die Dateien sind dann nicht nur Eins.java sondern hans\daten\Eins.java und so.

Aber ich würde Dir generell empfehlen, recht zügig zu einer IDE Deiner Wahl zu wechseln um dann nicht mehr von Hand auf der Kommandozeile zu arbeiten.
 
Aber ich würde Dir generell empfehlen, recht zügig zu einer IDE Deiner Wahl zu wechseln um dann nicht mehr von Hand auf der Kommandozeile zu arbeiten.
Ich komme mit der Kommandozeile hervorragend zurecht; aber ich werde wohl später der Effizienz willen und damit meine Arbeitskraft dem Zeitgeist entsprechend besser ausgenutzt werden kann auf eine IDE umsteigen. Ich habe gestern nebenher Eclipse installiert.
 
Ja und nein.

Beim Import ist in erster Linie der Classpath wichtig, damit die übersetze Klasse gefunden wird. Daher hat der Java Compiler die class Dateien in entsprechenden Verzeichnissen abgelegt.

Der Compiler sucht aber auch bei der Übersetzung nach der Klasse. Wenn die Klasse auf dem Classpath nicht zu finden ist, dann sucht er auch nach der Source Datei. Aber diese sucht er dann in daten/hans/ und nicht im aktuellen Verzeichnis.

Daher kommt der Fehler bei der Übersetzung. Du sagst ihm, dass er die Datei Eins.java übersetzen soll und dann kommt die Meldung:
file does not contain class Eins
Die Datei enthält nicht die Klasse Eins sondern die Klasse daten.hans.Eins - das macht einen kleinen Unterschied. Erstes ist eine Klasse EIns im unnamed package. Zweites eine Klasse Eins in hans.daten.

Das es bei irgendwelchen Versuchen auch mal geklappt hat, liegt dann daran, dass Du eine Klasse übersetzt hast, die EIns und Zwei braucht und diese Klassen im Classpath gefunden wurden. Es wurde da also vermutlich nur Programm.java übersetzt und EIns / Zwei aus den class Dateien gelesen (Die ja in .\hans\daten zu finden waren nach Deiner Aufstellung).

Also nur um es noch einmal deutlich zu sagen:

Es spielt für dein Programm.java keinen Unterschied ob Du da die Klassen einzeln per Import hinzufügst:
Java:
import hans.daten.Eins;
import hans.daten.Zwei;
Oder ob Du den ganzen Namespace einbindest:
import hans.daten.*;

Generell ist aber ein Import auf den Namespace selbst, wie ihn @Samka vorgeschlagen hat, nicht notwendig. Also kein:
import hans.daten;

Ich komme mit der Kommandozeile hervorragend zurecht; aber ich werde wohl später der Effizienz willen und damit meine Arbeitskraft dem Zeitgeist entsprechend besser ausgenutzt werden kann auf eine IDE umsteigen. Ich habe gestern nebenher Eclipse installiert.
Ok, es ist schön, dass Du mit der Kommandozeile zurecht kommst. Die kann auch zukünftig sehr interessant sein. Nur eben bestehen Java Programme oft aus einigen Dateien und haben auch Abhängigkeiten. Das alles auf der Kommandozeile zu machen wird dann sehr mühselig.
Daher ist es schon eine gute Idee, da auf ein Build Tool zu setzen. Ob das nun ein IDE Internes Projekt ist oder ein Tool wie Maven oder Gradle verwendet wird, ist da erst einmal nebensächlich. (Ich würde aber mittelfristig auf jeden Fall zu Maven oder Gradle raten!)

Ein großer Vorteil ist auch die Unterstützung beim schreiben von Java Code, da die IDE viele hilfreiche Vorschläge macht und man beim Schreiben schon Hinweise bekommt.
 
Ich danke für alle Hinweise und Hilfeversuche! Nach längerer Lektüre am heutigen Abend in einschlägiger Literatur habe ich es jetzt offenbar richtig gemacht. Die erfolgreiche Vorgehensweise habe ich in der angehängten Datei dokumentiert.

Falls jemand dazu aus seinem Kenntnis- und Erfahrungsschatz noch Hilfreiches anmerken möchte, lese ich es gerne und denke darüber nach.
 

Anhänge

Wenn heute jemand in meiner Gegenwart auf der Straße das Wort "Package" benutzt, dann kann ich für nichts garantieren. ;-)

Ich hoffe, ich habe nur zu wenig geschlafen; eine ähnliche Fehlermeldung nervt mich heute schon den halben Nachmittag.
 
Evtl. hilft Dir der Gedanke: Wenn Du erst einmal eine IDE nutzt, dann hat sich diese Problematik eigentlich erledigt. Da hast Du dann eine kompetente Unterstützung und die Entwicklungsumgebung macht sehr viel für Dich. Und gewisse Fehler werden auf Knopfdruck korrigiert für Dich.
 
  • Gibt es eine Möglichkeit, ein frei zugängliches Hilfsmittel, um den Fehler "error: cannot find symbol" genauer zu untersuchen?
  • Könnte mir jdb helfen, das Problem genauer zu verstehen und einzugrenzen?
Nach 18 Uhr werde ich noch einmal einen systematischen Versuch unternehmen, das aktuelle Problem einzugrenzen.
Bis dahin afk.
 
Also in der Regel braucht es nicht mehr als eine Entwicklungsumgebung. Und wir können Dir gerne helfen, das Problem einzugrenzen. Wenn Du mich direkt anschreibst, dann kann man von mir aus auch gerne eine kurze Online Session machen, in der man das angeht. Oder Du stellst mir Dein Projekt mal als ZIP zur Verfügung und ich schaue dann mal.
 

Zurück
Oben