2013-03-04 7 views
12

Ich arbeite an einem Projekt mit hohen Sicherheitsanforderungen. Eine Voraussetzung ist, unsere Gläser zu versiegeln.Mockito versiegelte Pakete

Da wir Gläser verschlossen, viele unserer JUnit-Tests nicht bestanden mit dem folgenden Fehler:

java.lang.SecurityException: sealing violation: package [a.dependency.package] is sealed 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:234) 
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at java.lang.Class.getDeclaredMethods0(Native Method) 
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2427) 
    at java.lang.Class.getDeclaredMethods(Class.java:1791) 
    at org.mockito.cglib.core.ReflectUtils.addAllMethods(ReflectUtils.java:349) 
    at org.mockito.cglib.proxy.Enhancer.getMethods(Enhancer.java:422) 
    at org.mockito.cglib.proxy.Enhancer.generateClass(Enhancer.java:457) 
    at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) 
    at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217) 
    at org.mockito.cglib.proxy.Enhancer.createHelper(Enhancer.java:378) 
    at org.mockito.cglib.proxy.Enhancer.createClass(Enhancer.java:318) 
    at org.mockito.internal.creation.jmock.ClassImposterizer.createProxyClass(ClassImposterizer.java:93) 
    at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:50) 
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:54) 
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:45) 
    at org.mockito.Mockito.spy(Mockito.java:991) 
    at [...] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27) 
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

Es sieht aus wie das Problem durch Mockito verursacht:

Wir "Mock" und „Spion "Klassen, die von externen versiegelten Gläsern kommen, und die von Mockito generierten" Scheinklassen "haben dasselbe Paket wie die" verspotteten Klassen ".

Da das Paket aus dem Abhängigkeitsjar versiegelt ist, kann das getestete jar keine Klasse im selben Paket erstellen (der URLClassLoader überprüft, dass dasselbe Paket nicht aus verschiedenen versiegelten Gläsern verwendet wird).

Ich habe versucht, eine spezifische SecurityManager .policy-Datei für Junit-Tests hinzuzufügen, aber ich habe keine Eigenschaft gefunden, die es erlaubt, Klassen innerhalb eines Pakets zu haben, das bereits durch eine Abhängigkeit versiegelt ist.

Darüber hinaus scheint es, dass der URLClassLoader keine Option hat, Siegelverletzung Kontrolle zu entfernen.

Die von uns verwendete Version von Mockito ist 1.8.5. Ich habe versucht, die neueste Version (1.9.5) zu verwenden, aber es hat den Fehler nicht behoben.

Wenn jemand eine Idee hat ...

+0

In welcher Version von Mockito laufen Sie? – bowmore

+0

Warum haben Sie sich entschieden, Ihre Gläser zu versiegeln? Auf eine nicht verwandte Anmerkung ... Willkommen zu stackoverflow, haben Sie etwas rep! – bakoyaro

+0

Danke Bakoyaro! – Syrdek

Antwort

3

Sie können dieses Problem umgehen, indem Züge in einem anderen Paket setzen und wenn Mock Prüfung, die anstelle der Klassen in Ihrem verschlossenen Gefäß trait. Das könnte als Sicherheitsbedenken ausgelegt werden, aber Sie können leicht dagegen argumentieren.

Sie könnten ein Glas versiegeln, das Ihren gesamten unverschlossenen Code importiert und dort kein Verhalten hinzufügt. Das würde Ihrem Kunden die Sicherheit geben, die er benötigt, aber Sie müssen sich nicht mit den Einschränkungen in Tests oder anderen Implementierungen herumschlagen, in denen Sie diese Anforderung nicht haben.

Ich bin sicher, dass Sie Abhängigkeiten verwenden, die nicht versiegelt sind, so dass Sie nur Ihren eigenen testbaren Code eine Abhängigkeit des versiegelten Glases auch machen.

+0

Schließlich entschieden wir uns, eine versiegelte Kopie unserer Gläser für Testzwecke zu haben. Die verschlossenen Gläser werden in die "Produktionsverteilung" aufgenommen. Danke für Ihre Hilfe ! – Syrdek

1

Sie könnten über Möglichkeiten nachdenken, diese Tests gegen Code auszuführen, der nicht in versiegelten Gläsern enthalten ist. Entweder bauen Sie auch versiegelte Gläser, und verwenden Sie sie zum Testen, oder entpacken Sie die Gläser vor dem Testen.

0

Ich hatte in letzter Zeit mit Mockito.spy und signierten Gläsern zu tun.

Eigentlich wäre eine Lösung, die Testaufgabe zu zwingen, alle problematischen Gläser (d. H. Die signierten) zu signieren.


Mit Apache Ant Sie ein Makro

<macrodef name="unsignjar"> 
    <attribute name="jarFile" /> 
    <sequential> 
     <jar update="yes" 
      jarfile="@{jarFile}.tmp"> 
      <zipfileset src="@{jarFile}"> 
       <include name="**"/> 
       <exclude name="META-INF/*.SF"/> 
       <exclude name="META-INF/*.DSA"/> 
       <exclude name="META-INF/*.RSA"/> 
      </zipfileset> 
     </jar> 
     <move file="@{jarFile}.tmp" 
       tofile="@{jarFile}" 
       overwrite="true" /> 
    </sequential> 
</macrodef> 

definieren und es dann wie folgt in dem Aufruf:

<target name="unsign-problematic-jars"> 
    <unsignjar jarFile="my-signed.jar" /> 
</target> 

Mit Apache Maven, Sie kann tun, wie in this ans vorgeschlagen wer, so greifen Sie auf das maven-jarsigner-plugin Plugin zurück.