5

问题

简单流程请求: 查找中的所有扩展名List.classjava.util

这是我正在使用的来源:

Reflections reflections = new Reflections("java.util");
Set<Class<?>> subtypes = reflections.getSubTypesOf(List.class);

很简单,对吧?

它适用于 IntelliJ IDEA 和 Eclipse,但当我通过 Maven 运行测试时它不起作用。我尝试使用org.reflections.util.ConfigurationBuilder's 提供的方法添加东西来添加 URL 和过滤包名称,但没有运气。

有什么建议么?

我浏览了这篇文章,但无法正常工作:“使用反射谷歌库的单元测试仅在由 Maven 执行时失败

代码

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>ohno</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>org.reflections</groupId>
      <artifactId>reflections</artifactId>
      <version>0.9.10</version>
    </dependency>

    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>6.9.10</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

示例.java

package com.example.uhoh;

import org.reflections.Reflections;
import java.util.Set;

public class Sample {

  @SuppressWarnings ("unchecked")
  public static Set<Class<?>> lookup(Class<?> type) {
    Reflections reflections = new Reflections("java.util");
    return (Set<Class<?>>) reflections.getSubTypesOf(type);
  }
}

SampleTest.java

package com.example.uhoh;

import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.List;
import java.util.Set;

@Test
public class SampleTest {

  public void testSample() {
    Set<Class<?>> result = Sample.lookup(List.class);
    Assert.assertNotNull(result, "NULL returned.");
    Assert.assertFalse(result.isEmpty(), "Unable to find any extensions of java.util.List");
  }
}

输出

在 IDE 中工作 在 IDE 中工作的示例

Maven 输出

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.uhoh.SampleTest
Configuring TestNG with: org.apache.maven.surefire.testng.conf.TestNG652Configurator@4e515669
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.261 sec <<< FAILURE!
(com.example.uhoh.SampleTest)  Time elapsed: 0.071 sec  <<< FAILURE!
java.lang.AssertionError: Unable to find any extensions of java.util.List expected [false] but found [true]
    at org.testng.Assert.fail(Assert.java:94)
    at org.testng.Assert.failNotEquals(Assert.java:513)
    at org.testng.Assert.assertFalse(Assert.java:63)
    at com.example.uhoh.SampleTest.testSample(SampleTest.java:15)


Results :

Failed tests:   (com.example.uhoh.SampleTest): Unable to find any extensions of java.util.List expected [false] but found [true]

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0

并行错误

Code public void testSample() { Class[] dataTypes = { ArrayList.class, LinkedList.class, List.class, AbstractList.class, Collection.class, Map.class, Properties.class };

  Arrays.stream(dataTypes).parallel().forEach(next -> {
    Set<Class<?>> result = Sample.lookup(next);
    Assert.assertNotNull(result, "NULL returned.");
    Assert.assertFalse(result.isEmpty(), "Unable to find any extensions of java.util.List");
  });
}

Maven Output

java.lang.IllegalStateException: java.lang.IllegalStateException: zip file closed

4

2 回答 2

6

I just encountered the same problem with Reflections library (version 0.9.11), only when executing unit tests from Maven builds. A simple POM file change to my Surefire plugin fixed this for me.

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.21.0</version>
            <configuration>
                <useSystemClassLoader>false</useSystemClassLoader>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.21.0</version>
            <configuration>
                <useSystemClassLoader>false</useSystemClassLoader>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>integration-test</goal>
                        <goal>verify</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

The <useSystemClassLoader> config parameter defaults to 'true'. Forcing it to 'false' seems to resolve the classloader problem in my unit tests.

于 2018-06-06T12:59:17.207 回答
2

To fix your issue, use Reflections' ConfigurationBuilder to manually set the URL for the jar that contains the class. This works in IntelliJ, and when invoking the Surefire plugin using command line Maven, mvn test.

Sample.java

public static Set<Class<?>> lookup(Class<?> type) {
    ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

    // For List.class, this will be a path to rt.jar.
    configurationBuilder.addUrls(ClasspathHelper.forClass(type));

    Reflections reflections = new Reflections(configurationBuilder);
    return (Set<Class<?>>) reflections.getSubTypesOf(type);
}
于 2016-07-09T22:24:25.943 回答