ByteBuddy:如何使用 java 中的 类 进行测试。*
ByteBuddy: How to test with classes from java.*
我正在尝试为拦截从 java.io(例如 FileInputStream)对 类 的调用的代理编写单元测试。
我已经按照 and had a look at 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)
我试过将 SecurityManager 设置为 null,但没有成功:
System.setSecurityManager(null);
如果我没记错的话,拦截这样的类应该是可以的。这可能是由于使用了自定义 ClassLoader。但是我不知道需要更改什么...
除了 bootstrap class 加载程序之外,无法从任何 class 加载程序加载带有 java.
前缀的任何 class。此限制不是由 SecurityManager
强制执行的,而是硬编码到 ClassLoader
实现中的。
测试这些 classes 的唯一方法是:
- 在测试过程中调整名称以允许在另一个 class 加载程序中加载。
- 将 classes 加载到 bootstrap class 加载程序中(使用
ByteBuddyAgent
和 ClassInjector.ForInstrumentation
)。您仍然应该随机命名以保证测试的可重复性。
在你的情况下,只有选项 2 似乎可行。因为我不知道你的代理在做什么,我只能假设你试图操纵 FileInputStream
class 在任何情况下你都需要使用 bootstrap 加载程序注入作为 a此 class 的复制不适用于 class 的本机方法适配器。
我正在尝试为拦截从 java.io(例如 FileInputStream)对 类 的调用的代理编写单元测试。
我已经按照
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)
我试过将 SecurityManager 设置为 null,但没有成功:
System.setSecurityManager(null);
如果我没记错的话,拦截这样的类应该是可以的。这可能是由于使用了自定义 ClassLoader。但是我不知道需要更改什么...
除了 bootstrap class 加载程序之外,无法从任何 class 加载程序加载带有 java.
前缀的任何 class。此限制不是由 SecurityManager
强制执行的,而是硬编码到 ClassLoader
实现中的。
测试这些 classes 的唯一方法是:
- 在测试过程中调整名称以允许在另一个 class 加载程序中加载。
- 将 classes 加载到 bootstrap class 加载程序中(使用
ByteBuddyAgent
和ClassInjector.ForInstrumentation
)。您仍然应该随机命名以保证测试的可重复性。
在你的情况下,只有选项 2 似乎可行。因为我不知道你的代理在做什么,我只能假设你试图操纵 FileInputStream
class 在任何情况下你都需要使用 bootstrap 加载程序注入作为 a此 class 的复制不适用于 class 的本机方法适配器。