Java: Zwei Jars im Projekt mit derselben Klasse.

7

Ich habe ein Java-Projekt, das zwei importierte Gläser mit der gleichen Klasse ( com.sun.mail.imap.IMAPFolder ) verwendet. Gibt es eine Möglichkeit, explizit anzugeben, welches jar beim Importieren der Klasse verwendet werden soll? Verwenden:

%Vor%

scheint die Klasse in der Reihenfolge der Build-Pfad-Reihenfolge zu verwenden, aber das scheint aus irgendeinem Grund nicht der Fall zu sein, was

verursacht %Vor%

zur Laufzeit. Ich baue das Projekt in Eclipse.

    
Fenrir 12.10.2013, 22:02
quelle

5 Antworten

8

Sie können nicht tun, was Sie gerade in Ihrer Java-Quelle fragen. Java wurde dafür nicht entwickelt.

Dies ist eine schlimme Situation, die nur mit benutzerdefinierten Klassenladeprogrammen verlässlich behandelt werden kann, von denen jedes eines der benötigten Gefäße bereitstellt. Da Sie diese Frage in erster Linie stellen, ist dies wahrscheinlich nicht die Art, wie Sie gehen sollten, da dies eine Menge neuer zeitaufwendiger Probleme eröffnet.

Ich würde Ihnen dringend empfehlen, warum Sie zwei verschiedene Versionen desselben jars in Ihrem Klassenpfad finden und Ihr Programm so zu überarbeiten, dass Sie nur eine Version benötigen.

    
Thorbjørn Ravn Andersen 13.10.2013, 08:35
quelle
15
___ qstntxt ___

Ich habe ein Java-Projekt, das zwei importierte Gläser mit der gleichen Klasse ( ClassLoader ) verwendet. Gibt es eine Möglichkeit, explizit anzugeben, welches jar beim Importieren der Klasse verwendet werden soll? Verwenden:

%Vor%

scheint die Klasse in der Reihenfolge der Build-Pfad-Reihenfolge zu verwenden, aber das scheint aus irgendeinem Grund nicht der Fall zu sein, was

verursacht %Vor%

zur Laufzeit. Ich baue das Projekt in Eclipse.

    
___ antwort19340327 ___

Wenn eine Klasse geladen wird, wird die erste Implementierung zurückgegeben, die dem angeforderten vollständig qualifizierten Namen entspricht, der für das relevante ClassLoader sichtbar ist. Alle anderen Implementierungen mit demselben vollständig qualifizierten Namen sind für diese java -cp A.jar:B.jar ExampleMain effektiv verborgen.

Was dies in einer standardmäßigen Java SE-Anwendung bedeutet, ist, dass die erste Codebasis (dh ein jar), die auf dem Klassenpfad mit der erforderlichen Klasse aufgelistet ist, diese bereitstellt, und alle anderen Codebasenimplementierungen der gleichen vollständig qualifizierten Klasse sind ausgeblendet .

Beispiel:

Nehmen Sie an, dass A.jar die kompilierte Klasse

enthält %Vor%

Nehmen Sie an, dass B.jar die kompilierte Klasse

enthält %Vor%

Beachten Sie, dass beide Klassen denselben vollqualifizierten Namen haben.

Angenommen, Hauptklasse ist

%Vor%

Wenn ich mein Programm mit

aufrufen würde

Hello, A!

Die Ausgabe ist: java -cp B.jar:A.jar ExampleMain

Wenn ich den Klassenpfad wie folgt umkehren

Hello, B!

Die Ausgabe ist: %code%

    
___ answer26431254 ___

Ja, es gibt eine Möglichkeit, das Problem zu beheben. In meinem Szenario habe ich zwei Klassen mit dem gleichen Namen und dem gleichen Pfad und die Sonnenfinsternis importiert immer die falsche. Was ich getan habe, ist die Änderung der Jar-Reihenfolge im Build-Pfad und Eclipse wird die erste im Build-Pfad auswählen.

    
___ answer36772526 ___

Wenn Sie eine IDE verwenden, können Sie die Reihenfolge für den Export der Dateien in den Klassenlader festlegen.

Ich arbeite an Eclipse und ich benutze Maven. Wenn ich das Projekt mit maven installiere, erzeugt es viele zusätzliche Jars (die ich in meinen Abhängigkeiten nicht definiert habe) und es gab eine Datei %code% , die in 2 JAR-Dateien vorhanden war und die dritte Instanz der gleichen Datei befand sich ebenfalls in JRE7.

Um sicherzustellen, dass die richtige Datei abgerufen wird, musste ich nur zu Java Build Path gehen - & gt; Bestellung und Export Wählen Sie die Jar-Datei, die der Classloader bevorzugen soll, und verschieben Sie sie mit der Schaltfläche "Nach oben".

So sieht es aus. Bitte beachten Sie, dass dieses Bild für Eclipse ist. Aber für andere IDEs würde es definitiv einen ähnlichen Weg geben, dies auszuarbeiten.

    
___ tag123eclipse ___ Eclipse ist eine Open-Source-IDE und Plattform zum Erstellen von Anwendungen. Es gibt eine Vielzahl von Plugins für verschiedene Programmiersprachen und andere entwicklungsorientierte Werkzeuge (wie Modellierung, Datenbanksuche usw.). Dieses Tag sollte nur für Fragen verwendet werden, die sich speziell mit der Eclipse-IDE oder der Eclipse-Plattform befassen, nicht jedoch für generalisierte (Java, Android usw.) Programmierthemen. ___ answer19341314 ___

1) Allgemein: Ja, Sie können dieselbe Klasse in verschiedenen .jar-Dateien verwenden: Sie müssen sie nur mit einem vollständig qualifizierten Paketnamen disambiguieren. Die "Date" -Klasse (vorhanden in java.util und java.sql) ist ein gutes Beispiel.

2) Wenn Sie zwei DIFFERENT .jar-Dateien haben, die die SAME vollständig qualifizierten Paketnamen haben ... besteht die Möglichkeit, dass Sie einen Konflikt haben. Auch wenn Sie die InvocationTargetException umgehen können, indem Sie mit dem Klassenlader spielen, können Sie dennoch auf andere Probleme stoßen. In diesem Fall klingt es so, als hätten Ihre beiden .jar-Dateien zwei verschiedene Implementierungen der JavaMail-API. Ich weiß es nicht.

3) Die sicherste Wette besteht darin, alle Referenzen Ihres Programms zu erfüllen, OHNE einen Konflikt zu riskieren. Ich glaube, wenn Sie die "offizielle" .jar von Oracle JavaMail-Webseite nahm, können Sie dies tun:

Ссылка

'Ich hoffe, das hilft!

    
___ tag123class ___ Eine Vorlage zum Erstellen neuer Objekte, die die allgemeinen Zustände und Verhaltensweisen beschreibt. NICHT MIT CSS-KLASSEN VERWECHSELN. Verwenden Sie stattdessen [css]. ___ tag123import ___ Bezieht sich allgemein auf das Verschieben von Daten aus einer externen Quelle in die Plattform, das Programm oder den Datensatz. ___ tag123java ___ Java (nicht zu verwechseln mit JavaScript oder JScript oder JS) ist eine universelle objektorientierte Programmiersprache, die für die Verwendung in Verbindung mit der Java Virtual Machine (JVM) entwickelt wurde. "Java-Plattform" ist der Name für ein Computersystem, auf dem Tools zum Entwickeln und Ausführen von Java-Programmen installiert sind. Verwenden Sie dieses Tag für Fragen, die sich auf die Java-Programmiersprache oder Java-Plattform-Tools beziehen. ___ qstnhdr ___ Java: Zwei Jars im Projekt mit derselben Klasse. ___ answer19343282 ___

Sie können nicht tun, was Sie gerade in Ihrer Java-Quelle fragen. Java wurde dafür nicht entwickelt.

Dies ist eine schlimme Situation, die nur mit benutzerdefinierten Klassenladeprogrammen verlässlich behandelt werden kann, von denen jedes eines der benötigten Gefäße bereitstellt. Da Sie diese Frage in erster Linie stellen, ist dies wahrscheinlich nicht die Art, wie Sie gehen sollten, da dies eine Menge neuer zeitaufwendiger Probleme eröffnet.

Ich würde Ihnen dringend empfehlen, warum Sie zwei verschiedene Versionen desselben jars in Ihrem Klassenpfad finden und Ihr Programm so zu überarbeiten, dass Sie nur eine Version benötigen.

    
___ tag123jar ___ JAR-Datei (oder Java ARchive) aggregiert viele Dateien zu einer Datei. JAR-Dateien bauen auf dem ZIP-Dateiformat auf. ___
Dev 12.10.2013 23:41
quelle
0

1) Allgemein: Ja, Sie können dieselbe Klasse in verschiedenen .jar-Dateien verwenden: Sie müssen sie nur mit einem vollständig qualifizierten Paketnamen disambiguieren. Die "Date" -Klasse (vorhanden in java.util und java.sql) ist ein gutes Beispiel.

2) Wenn Sie zwei DIFFERENT .jar-Dateien haben, die die SAME vollständig qualifizierten Paketnamen haben ... besteht die Möglichkeit, dass Sie einen Konflikt haben. Auch wenn Sie die InvocationTargetException umgehen können, indem Sie mit dem Klassenlader spielen, können Sie dennoch auf andere Probleme stoßen. In diesem Fall klingt es so, als hätten Ihre beiden .jar-Dateien zwei verschiedene Implementierungen der JavaMail-API. Ich weiß es nicht.

3) Die sicherste Wette besteht darin, alle Referenzen Ihres Programms zu erfüllen, OHNE einen Konflikt zu riskieren. Ich glaube, wenn Sie die "offizielle" .jar von Oracle JavaMail-Webseite nahm, können Sie dies tun:

Ссылка

'Ich hoffe, das hilft!

    
paulsm4 13.10.2013 02:44
quelle
0

Ja, es gibt eine Möglichkeit, das Problem zu beheben. In meinem Szenario habe ich zwei Klassen mit dem gleichen Namen und dem gleichen Pfad und die Sonnenfinsternis importiert immer die falsche. Was ich getan habe, ist die Änderung der Jar-Reihenfolge im Build-Pfad und Eclipse wird die erste im Build-Pfad auswählen.

    
biao li 17.10.2014 18:30
quelle
0

Wenn Sie eine IDE verwenden, können Sie die Reihenfolge für den Export der Dateien in den Klassenlader festlegen.

Ich arbeite an Eclipse und ich benutze Maven. Wenn ich das Projekt mit maven installiere, erzeugt es viele zusätzliche Jars (die ich in meinen Abhängigkeiten nicht definiert habe) und es gab eine Datei org.w3c.dom.Element , die in 2 JAR-Dateien vorhanden war und die dritte Instanz der gleichen Datei befand sich ebenfalls in JRE7.

Um sicherzustellen, dass die richtige Datei abgerufen wird, musste ich nur zu Java Build Path gehen - & gt; Bestellung und Export Wählen Sie die Jar-Datei, die der Classloader bevorzugen soll, und verschieben Sie sie mit der Schaltfläche "Nach oben".

So sieht es aus. Bitte beachten Sie, dass dieses Bild für Eclipse ist. Aber für andere IDEs würde es definitiv einen ähnlichen Weg geben, dies auszuarbeiten.

    
user1295300 21.04.2016 14:22
quelle

Tags und Links