2016-05-23 36 views
1

我正在嘗試爲攔截對來自java.io的類的調用(例如FileInputStream)的代理編寫UnitTest。ByteBuddy:如何使用java測試類。*

我按照給出的提示here,看看ByteBuddys own UnitTests。 。

private ClassLoader classLoader; 

@Before 
@AgentAttachmentRule.Enforce 
public void setUp() throws Exception 
{ 
    classLoader = new ByteArrayClassLoader.ChildFirst(getClass().getClassLoader(), 
              ClassFileExtraction.of(FileInputStream.class), 
              DEFAULT_PROTECTION_DOMAIN, 
              AccessController.getContext(), 
              ByteArrayClassLoader.PersistenceHandler.MANIFEST, 
              PackageDefinitionStrategy.NoOp.INSTANCE); 
} 

@Test 
public void testAgentForFileInputStream() throws Exception 
{ 
    MyAgent.premain(""); 
    Class<?> type = classLoader.loadClass(FileInputStream.class.getName()); 
    type.getDeclaredMethod("open").invoke("test"); 
} 

類似的測試非Java *類工作得很好,但是在這裏我得到:

java.lang.SecurityException: Prohibited package name: java.io 

at java.lang.ClassLoader.preDefineClass(ClassLoader.java:659) 
at java.lang.ClassLoader.defineClass(ClassLoader.java:758) 
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader.findClass(ByteArrayClassLoader.java:197) 
at net.bytebuddy.dynamic.loading.ByteArrayClassLoader$ChildFirst.loadClass(ByteArrayClassLoader.java:554) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 

我已經嘗試設置安全管理器爲空,沒有成功:

System.setSecurityManager(null); 

如果我沒有弄錯,攔截這樣的類應該是可能的。這可能是由於使用了自定義ClassLoader。但是我不知道需要更改什麼......

回答

2

不可能從任何類加載器加載任何帶有java.前綴的類,而是引導類加載器。此限制不是由SecurityManager強制執行,而是硬編碼到ClassLoader實施中。

,以測試這些類的唯一方法是:

  1. 在測試過程中調整的名稱,以便裝載在另一個類加載器。
  2. 將類加載到引導程序類加載程序中(使用ByteBuddyAgentClassInjector.ForInstrumentation)。您仍然應該隨機化名稱以保證測試的可重複性。

就你而言,只有選項2似乎是可行的。因爲我不知道你的代理正在做什麼,所以我只能假設你試圖操縱FileInputStream類,在任何情況下你都需要使用引導加載器注入,因爲這個類的複製不能用類的本地方法適配器。