2017-07-10 3 views
5

Wenn ich diesen Test ausführen (JMockit und TestNG verwendet wird, nicht sicher, ob das relevant):Modul java.base nicht Modul liest java.desktop

public class Test { 
    @Test public void test(@Mocked ProcessBuilder pb) throws IOException { 
    new Expectations() {{ pb.start(); result = null; }}; 
    assertNull(m()); 
    } 

    public static Process m() throws IOException { 
    return new ProcessBuilder("").start(); 
    } 
} 

Ich erhalte diese Ausnahme:

java.lang.IllegalAccessError: class java.lang.ProcessBuilder (in module java.base) cannot access class javax.print.PrintException (in module java.desktop) because module java.base does not read module java.desktop 

at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java) 
.... 

Ich benutze Build 177.

Ich kann den Test mit --add-reads java.base=java.desktop Argument wiederholen und es funktioniert gut, aber ich verstehe nicht wirklich, was hier passiert.

Warum bekomme ich diese Ausnahme?

+3

Meine Vermutung wäre eine Interaktion mit Klassen, die implizit geladen werden; 'PrintException' erweitert' IOException' und fühlt sich * wie die unerklärliche 'HeadlessException' an, wenn etwas benutzt wird, das nicht offensichtlich Swing-bezogen ist. Ich schlage vor, einen Fehler über eine mögliche versteckte Klassenabhängigkeit einzureichen. – chrylis

+0

Sind die Klassen/jars auf dem Modulpfad oder dem Klassenpfad? Sind irgendwelche Module für Ihren Code definiert? –

+0

@MichaelOster auf dem Klassenpfad - Ich habe kein Modul definiert. Es ist ein einfaches Projekt mit einer pom.xml mit einer Abhängigkeit von TestNG und jmockit und einer Datei (die Test-Klasse in der Frage). Der Pom enthält eine argLine von '-Djdk.attach.allowAttachSelf' für todsichere Datei, damit jmockit ausgeführt werden kann. – assylias

Antwort

2

Die issue wurde für JMockit 1.34 behoben.

Beim Start ändert JMockit eine JRE-Klasse (durch Hinzufügen einiger Felder), um das Mocking von JRE-Klassen zu unterstützen. Die tatsächliche Klasse, die geändert wird, ist willkürlich, und javax.print.PrintException wurde (als eine sekundäre Auswahl) verwendet, nur weil es normalerweise nie in einem typischen Testlauf geladen wird. Auf JDK 9 ist diese Klasse nicht vom "Basis" -Modul aus zugänglich, daher wurde sie jetzt durch eine andere Klasse ersetzt.

8

Der IllegalAccessError weist darauf hin, dass JMockit ProcessBuilder (in java.base) mit einem Verweis auf eine Ausnahme im Modul java.desktop instrumentiert hat. Ich weiß nicht, warum sie diese Ausnahme gewählt haben, das könnte etwas für die JMockit Mailingliste sein. Es erklärt jedoch, warum --add-reads das Problem behebt.

+3

Danke - Ich habe das Problem dort angesprochen: https://github.com/jmockit/jmockit1/issues/428 – assylias