2013-03-04 33 views
12

Tôi đang làm việc trên một dự án có những hạn chế về bảo mật nghiêm trọng. Yêu cầu là niêm phong các lọ của chúng tôi.mockito vs gói kín

Kể từ khi chúng tôi kín lọ, rất nhiều junit-kiểm tra của chúng tôi thất bại với các lỗi sau:

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) 

Dường như vấn đề là do Mockito:

Chúng tôi "giả" và "gián điệp "các lớp học đến từ một số lọ kín bên ngoài, và" các lớp mô hình "được tạo ra bởi Mockito có cùng một gói so với" các lớp giả ".

Vì gói từ bình phụ thuộc được niêm phong, bình thử nghiệm không thể tạo lớp trong cùng một gói (URLClassLoader kiểm tra xem gói đó không được sử dụng từ các lọ kín khác nhau).

Tôi đã cố gắng thêm một SecurityManager cụ thể.

Hơn nữa, có vẻ như URLClassLoader không có tùy chọn để xóa kiểm tra vi phạm niêm phong.

Phiên bản Mockito chúng tôi sử dụng là 1.8.5. Tôi đã cố gắng sử dụng phiên bản mới nhất (1.9.5) nhưng nó không sửa lỗi.

Nếu ai đó có một ý tưởng ...

+0

Bạn đang chạy phiên bản Mockito nào? – bowmore

+0

Trên một lưu ý hơi liên quan, tại sao bạn chọn để niêm phong lọ của bạn? Trên một lưu ý không liên quan ... Chào mừng bạn đến stackoverflow, có một số đại diện! – bakoyaro

+0

Cảm ơn bạn bakoyaro! – Syrdek

Trả lời

3

Bạn có thể làm việc này bằng cách đặt những đặc điểm trong một gói khác nhau và khi kiểm tra giả rằng tính trạng thay vì các lớp trong lọ kín của bạn. Điều đó có thể được hiểu là mối quan tâm về bảo mật nhưng bạn có thể tranh luận với điều đó khá dễ dàng.

Bạn có thể đóng dấu một lọ nhập khẩu tất cả mã chưa được niêm phong của bạn và không thêm bất kỳ hành vi nào ở đó. Điều đó sẽ cung cấp cho khách hàng của bạn sự bảo mật mà anh ta cần, nhưng tránh bạn phải đối phó với các hạn chế trong các bài kiểm tra hoặc các triển khai khác mà bạn không có yêu cầu này.

Tôi chắc chắn rằng bạn đang sử dụng các phụ thuộc chưa được niêm phong, vì vậy bạn chỉ cần tạo mã có thể kiểm tra của riêng mình cũng là một phụ thuộc của bình bịt kín.

+0

Cuối cùng, chúng tôi quyết định có một bản sao chưa niêm kín của các lọ của chúng tôi cho mục đích thử nghiệm. Các lọ kín sẽ được bao gồm trong "phân phối sản xuất". Cảm ơn sự giúp đỡ của bạn ! – Syrdek

1

Bạn có thể xem xét các cách để chạy các thử nghiệm này đối với mã không có trong các lọ kín. Hoặc là xây dựng các lọ kín và sử dụng chúng để kiểm tra, hoặc giải nén các lọ trước khi thử nghiệm.

0

Gần đây tôi đã phải đối phó với Mockito.spy và các lọ đã ký.

Thực ra, một giải pháp sẽ là bắt buộc nhiệm vụ kiểm tra phải hủy bỏ tất cả các lọ có vấn đề (tức là những người đã ký).


Với Apache Ant bạn có thể định nghĩa một macro

<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> 

và sau đó gọi nó như thế nào trong những điều sau đây:

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

Với Apache Maven, bạn có thể làm như được đề xuất trong this ans wer, vì vậy bạn sử dụng plugin maven-jarsigner-plugin.