Skip to main content
 首页 » 编程设计

执行 jacoco 准备代理时,使用反射捕获的 Java 注释将不起作用

2024年08月06日19powertoolsteam

我有一个多模块 Maven 项目。这有一组由 jaxb 使用 xsd 生成的类。下面给出了此类的示例。 (没有 getter 和 setter)

@XmlRootElement(name = "IPPAMUser") 
public class IPPAMUser { 
 
@XmlElement(name = "UserName", required = true) 
protected String userName; 
@XmlElement(name = "PAMInstanceID", required = true) 
protected String pamInstanceID; 
@XmlElement(name = "Product", required = true) 
protected String product; 
@XmlElement(name = "Password", required = true) 
protected String password; 
@XmlElement(name = "PasswordAlogo", required = true) 
protected String passwordAlogo; 
@XmlElement(name = "LastUpdatedOn", required = true) 
protected String lastUpdatedOn; 
@XmlElement(name = "IsGenerated") 
protected boolean isGenerated; 
@XmlElement(name = "LastNotifiedOn", required = true) 
protected String lastNotifiedOn; 
} 

一个模块需要它们作为键值对。因此,一种使用反射编写的方法将它们转换为键值对列表。在该字段中,名称用作键,值用作其值。取如下。

Field[] fields = t.getClass().getDeclaredFields(); 
    for(Field field : fields) { 
        Annotation anotation = field.getAnnotation(XmlElement.class); 
        XmlElement xmlElement = (XmlElement) anotation; 
 
        String methodName; 
        String parameterValue = ""; 
        if(field.getType() == boolean.class){ 
            methodName = "is" + xmlElement.name(); 
        } else { 
            methodName = "get" + xmlElement.name(); 
        } 
        try { 
            Method method = t.getClass().getDeclaredMethod(methodName); 
            if(method.invoke(t) == null){ 
                continue; 
            } 
            parameterValue = method.invoke(t).toString(); 
        } catch (NoSuchMethodException e) { 
            log.error("Method not found. Method : " + methodName, e); 
            log.error("Stack trace : {}", AuthUtils.getPrintableStackTrace(e)); 
        } catch (InvocationTargetException e) { 
            log.error("Method invoking failed. Method : " + methodName, e); 
            log.error("Stack trace : {}", AuthUtils.getPrintableStackTrace(e)); 
        } catch (IllegalAccessException e) { 
            log.error("Illegal access " + e); 
            log.error("Stack trace : {}", AuthUtils.getPrintableStackTrace(e)); 
        } 
  } 

有一些测试用例使用了这种转换。它们工作正常并使用 maven build 执行。为了进行代码覆盖,添加了 jacoco-maven-plugin。运行时它不会生成 jacoco.exec 文件。根据这个post执行目标已添加到我的 pom 文件中。之后我的单元测试失败并给出空指针异常。根据堆栈跟踪,它是在执行“xmlElement.name()”时引起的,这意味着 xmlElement 为空。所以添加这个执行目标后反射无法获取注解。

我如何解决这个问题并使用 jacoco 或任何其他方式获取代码覆盖率报告。

提前致谢。

请您参考如下方法:

我自己想出解决方案。当 jacoco 准备代理时,它会在类中包含一些合成字段。因此,当它尝试获取它时,没有所需注释的合成字段包含在字段列表中。

作为反射中的最佳实践,检查您访问的每个字段的 isSynthetic()。这将避免您访问编译器添加的字段以及 jacoco 等工具。请参阅这些链接以获取更多引用。

synthetic field Jacoco synthetic field