Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hallo, ich komme momentan überhaupt nicht mit meinem Problem weiter.
In "Java ist auch eine Insel" steht, dass es sich mit ServiceLoader Programme realisieren lassen, die von konkreten Klassen unabhängig sind.
Das habe ich nun Versucht.
Es gibt eine Schnittstelle A. Es gibt eine konkrete Klasse die diese Schnittstelle implementiert B(A).
Nun gibt es eine dritte Klasse C, die mit Hilfe von ServieceLoader unabhängig von B sein soll.
Dabei erstelle ich unter "scr/META-INF/services" eine Datei mit dem Namen "packetnameInterface".A
Diese Datei hat kein Dateiende.
In die Datei schreibe ich: "paketNameKonkreteKlasse".B
Wenn ich nun versuche aus C heraus B zu starten: A.process.iterator().next();
package file_manager;
import java.util.ServiceLoader;
import file_manager.abstract_iterface_class.A
public final class C {
static ServiceLoader<A> gui = ServiceLoader.load(A.class);
public static void main(String args[]) {
gui.iterator().next();
}
Also ich arbeite mit netbeans.. und wenn mit "compilierter kram" der ordner build gemeint ist, dann ist da tatsächlich der Ordner META-INF zu finden.. wurde wahrscheinlci beim compilieren von scr nach build kopiert..
PS: und die Datei ist ebenfalls da drine
Poste die Exception doch bitte einmal. In welcher Zeile deines Codes meckert der Compiler? Wenn der Fehler sich nicht auf die Schnelle erschließen lässt, dann debugge dein Programm doch einmal in dem du Breakpoints setzt.
Poste die Exception doch bitte einmal. In welcher Zeile deines Codes meckert der Compiler? Wenn der Fehler nicht sich nicht auf die Schnelle erschließen lässt, dann debugge dein Programm doch einmal.
Gut (oder auch nicht). Ich habe gerade in einem Testprojekt (allerdings "leider" Eclipse) verschiedene Fehlerfälle ausprobiert. Der von Dir beschriebene kommt nur, wenn Java die Datei nicht findet. Als Referenz meine Ordnerstruktur im build-Ordner (bei mir heißt der nach Maven-Konvention target)
target/classes/de/... <-- Die ganzen Klassen in ihren Packages plus evtl zugehörige Resourcen (properties-Dateien etc
Damit klappt's bei Eclipse-Run. Was ich damit eigentlich nur zeigen will, ist dass alles zusammen liegen muss, damit's im Classpath liegt. Möglicherweise kannst Du Netbeans entsprechend konfigurieren.
-Implementierung geschrieben, die Datei "java.io.FileFilter" in META-INF/services/ erzeugt, dort den voll qualifizierten Klassennamen der Impl-Klasse eingetragen und dann folgenden Code zum Testen ausgeführt:
Java:
public static void main(String[] args) throws Exception {
ServiceLoader<FileFilter> loader = ServiceLoader.load(FileFilter.class);
System.out.println(loader);
final Iterator<FileFilter> iter = loader.iterator();
while (iter.hasNext()) {
System.out.println(iter.next());
}
Es zeigt mir genau eine Implementierungsinstanz an (genau die, die ich registriert habe). Das Programm lässt sich sowohl in Eclipse als auch von Kommandozeile mittels java-Aufruf ausführen.
Danke fuer die Hilfe, ich habe mien fehler gefunden.. und zwar habe ich den ordner falsch benannt wo die interface .class dateien lagen.. anstatt interface im Namen hinzuschreiben hatte ich da iterface stehen gehabt.. im Namen der Datei die im META ordner liegt hatte ich aber richtig interface stehen gehabt..
Allerdings habe ich gemerkt, dass man mit so einer methode nicht auf Konstruktor der Konkreten Klassendatei zugreifen hat, weshalb ich einfach zu objekt erstellung der konkreten klassen zurück muss ..
Wie lässt sich sonst mit ServiceLoader auf Konstruktor der implimetierenden Datei zugreifen?
Allerdings habe ich gemerkt, dass man mit so einer methode nicht auf Konstruktor der Konkreten Klassendatei zugreifen hat, weshalb ich einfach zu objekt erstellung der konkreten klassen zurück muss ..
Musst Du doch nicht. Der ServiceLoader ruft doch automatisch den public no-arg Konstruktor auf und Du hast Deine Instanz. Oder willst Du einen anderen verwenden?
Wie lässt sich sonst mit ServiceLoader auf Konstruktor der implimetierenden Datei zugreifen?
Wenn Du vorher nicht weißt, welche Konstruktoren es gibt, mit Reflection. Dann brauchste aber ServiceLoader überhaupt nicht bzw. es funktioniert auch nicht, wenn es keinen public no-arg Konstruktor gibt. Dann wäre Class.forName das Mittel der Wahl um Namen von Klassen zu konfigurieren, die man gerne laden möchte.
Musst Du doch nicht. Der ServiceLoader ruft doch automatisch den public no-arg Konstruktor auf und Du hast Deine Instanz. Oder willst Du einen anderen verwenden?
ich habe eine grafische Benutzeroberfläche programmiert. In dieser Klassendatei werden aber die meiste Events deklariert. Das heißt, der Klassaendatei mit grafischen Benutzeroberfläche müssen anere Klassenobjekte die für verarbeitung verantwortlich sind übergeben werden.
Das heißt der Konstruktor der GUI Klasse ist prametrisiert.
Ich habe gedacht den erstml mit Servce Loader irgendwie initialisieren zu können.
Wenn Du vorher nicht weißt, welche Konstruktoren es gibt, mit Reflection. Dann brauchste aber ServiceLoader überhaupt nicht bzw. es funktioniert auch nicht, wenn es keinen public no-arg Konstruktor gibt. Dann wäre Class.forName das Mittel der Wahl um Namen von Klassen zu konfigurieren, die man gerne laden möchte.
Das macht nichts , braucht man auch eher selten. Für Deinen Anwendungsfall wäre das auch nicht das Mittel der Wahl. Du hast ja eine GUI-Klasse, bei der Du die Konstruktoren kennst. Instanziere sie doch einfach direkt z.B. in der main und versorge sie mit den benötigten Services. Ggf. kann Dir ein Dependency Injection Framework einen Teil der Arbeit abnehmen. ServiceLoader ist hier wohl nicht das geeignete Mittel.
Das macht nichts , braucht man auch eher selten. Für Deinen Anwendungsfall wäre das auch nicht das Mittel der Wahl. Du hast ja eine GUI-Klasse, bei der Du die Konstruktoren kennst. Instanziere sie doch einfach direkt z.B. in der main und versorge sie mit den benötigten Services. Ggf. kann Dir ein Dependency Injection Framework einen Teil der Arbeit abnehmen. ServiceLoader ist hier wohl nicht das geeignete Mittel.
Außer den Unterschrichen in den Klassen- und Variablennamen. Das ist in Java sehr unüblich. Da benutzt man für zusammengesetzte Würder sog. CamelCase-Notation, bei Variablen mit Kleinbuchstaben beginnend, bei Klassennamen mit Großbuchstaben. Unterschriche werden in Java eigentlich nur bei static final "Konstanten" benutzt, weil hier alle Buchstaben groß sind und man deswegen CamelCase nicht anwenden kann. Zur Veranschaulichung mal folgendes Beispiel:
Java:
// camel case im Klassennamen zum Zusammensetzen von Wörtern
// geht auch mit Englisch (MySpecialGuiClass)
public class MeineSpezielleGuiKlasse {
// static final "Konstante" hier nur Großbuchstaben
// deswegen Wortzusammensetzung mit Unterstrich
private static final int EMPTY_LENGTH = 0;
// Variablennamen mit Kleinbuchstaben beginnend
// dann camel case für Zusammensetzen von Wörtern
private int screenWidth;
Ach ja, für Package-Namen gilt die gleiche Konvention wie für variablen (beginne mit Kleinbuchstaben, dann ggf. camel case, keine Unterstriche). Ich mach in Package Namen aber meist kein camel-case, weil auf UNIXEN Pfade case sensitiv sind und mich die Großbuchstaben nerven, wenn ich sie in der Konsole eingeben muss.