小编Moe*_*Pad的帖子

CompletableFuture/ForkJoinPool设置类加载器

我解决了一个非常具体的问题,其解决方案似乎是基本的:

我的(Spring)应用程序的类加载器层次结构是这样的: SystemClassLoader -> PlatformClassLoader -> AppClassLoader

如果我使用Java CompleteableFuture来运行线程.该ContextClassLoader线程的是: SystemClassLoader -> PlatformClassLoader -> ThreadClassLoader

因此,AppClassLoader虽然我必须访问任何类,但我无法访问任何类,因为所有外部库类都驻留在那里.

源代码库非常大,所以我不希望/不能将所有与线程相关的部分重写为其他内容(例如,将自定义执行程序传递给每个调用).

所以我的问题是:我怎样才能创建线程,例如CompleteableFuture.supplyAsync()使用AppClassLoader父母作为父母?(而不是PlatformClassloader)

我发现ForkJoinPool用于创建线程.但在我看来,一切都是静态的最终的.所以我怀疑即使在系统属性中设置自定义ForkJoinWorkerThreadFactory也会有所帮助.或者是吗?

编辑以回答评论中的问题:

  • 你在哪里部署?这是在jetty/tomcat /任何JEE容器内运行吗?

    • 我正在使用默认的Spring Boot设置,因此使用了内部tomcat容器.
  • 你有什么确切的问题?

    • 确切的问题是:java.lang.IllegalArgumentException:从类加载器中看不到从方法引用的org.keycloak.admin.client.resource.RealmsResource
  • 您提交给supplyAsync()的作业是从AppClassLoader创建的,不是吗?

    • supplyAsync从被称为MainThread它使用AppClassLoader.但是,调试应用程序会显示所有此类线程都具有PlatformClassLoader父级.至于我的理解,这是因为ForkJoinPool.commonPool()是在应用程序启动期间构建的(因为它是静态的),所以使用默认的类加载器作为父类PlatformClassLoader.因此,此池中的所有线程都将PlatformClassLoader作为ContextClassLoader的父级(而不是AppClassLoader).

    • 当我在内部创建自己的执行程序MainThread并将此执行程序传递给supplyAsync所有工作时 - 我可以在调试期间看到确实现在AppClassLoader是我的父项ThreadClassLoader.这似乎证实了我在第一种情况下的假设,即公共池MainThread至少不是在它自己使用时创建的 …

java spring classloader completable-future

13
推荐指数
4
解决办法
1238
查看次数

使用相同的测试测试多个接口实现 - JUnit4

我想为不同的接口实现运行相同的JUnit测试.我用@Parameter选项找到了一个很好的解决方案:

public class InterfaceTest{

  MyInterface interface;

  public InterfaceTest(MyInterface interface) {
    this.interface = interface;
  }

  @Parameters
  public static Collection<Object[]> getParameters()
  {
    return Arrays.asList(new Object[][] {
      { new GoodInterfaceImpl() },
      { new AnotherInterfaceImpl() }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

此测试将运行两次,首先使用GoodInterfaceImpl,然后使用AnotherInterfaceImpl类.但问题是我需要大多数测试用例是一个新对象.一个简化的例子:

@Test
public void isEmptyTest(){
   assertTrue(interface.isEmpty());
}

@Test
public void insertTest(){
   interface.insert(new Object());
   assertFalse(interface.isEmpty());
}
Run Code Online (Sandbox Code Playgroud)

如果在insertTest之后运行isEmptyTest则失败.

是否有选项可以使用新的实现实例自动运行每个测试用例?

顺便说一句:为接口实现clear()reset()方法实际上不是一个选项,因为我不需要它在生产代码中.

junit4

9
推荐指数
2
解决办法
2167
查看次数

从XML文件中删除节点(DOM4J,JAVA)

由于此主题相关的所有其他问题涉及到一个特定的编程问题(例如,"我得到一个NullPointerException当我尝试这样那样的")和答案是固定的编程错误,这里是一个简单的解决以下问题:

如何使用DOM4J从XML文件中删除节点?

java dom4j

4
推荐指数
1
解决办法
1440
查看次数

如何使用Gradle更改Spring Boot应用程序的端口?

一个简单的问题是:如何使用gradle更改Spring Boot应用程序端口?


如果您不使用gradle,这里已经列出了许多正确答案。因此,如果没有任何问题,请参阅此帖子。

port gradle spring-boot

2
推荐指数
3
解决办法
2121
查看次数