Jenkins によって生成された lint-result.xml を解析しようとしています。lint 結果ファイルを受け取り、それを XStream 1.4.1 (ドキュメントで見たものから現在 Jenkins で使用されているバージョン) で解析するスタンドアロン プロジェクトを作成しました。これはまったく問題なく動作します。ただし、コードを Jenkins プラグイン (ビルド後のプラグイン) に移動すると、次のエラーが発生します。
com.thoughtworks.xstream.mapper.CannotResolveClassException: com.peter.android_lint.parser.LintIssues : com.peter.android_lint.parser.LintIssues
at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:68)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:71)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:86)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:96)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:38)
at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:56)
at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:136)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:33)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:926)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:912)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:864)
at com.peter.android_lint.parser.LintParser.parse(LintParser.java:25)
at com.peter.ReportPublisher.findFiles(ReportPublisher.java:61)
at com.peter.ReportPublisher.perform(ReportPublisher.java:48)
at hudson.tasks.BuildStepMonitor$3.perform(BuildStepMonitor.java:36)
at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:814)
at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:786)
at hudson.model.Build$BuildExecution.post2(Build.java:183)
at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:733)
at hudson.model.Run.execute(Run.java:1592)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:46)
at hudson.model.ResourceController.execute(ResourceController.java:88)
at hudson.model.Executor.run(Executor.java:237)
パーサー クラス
public class LintParser {
private File lintResult;
public void parse(String fileName) {
lintResult = new File(fileName);
XStream xstream = new XStream();
xstream.alias("issues", LintIssues.class);
xstream.alias("issue", LintIssue.class);
xstream.alias("location", Location.class);
//xstream.processAnnotations(new Class[]{LintIssues.class, LintIssue.class, Location.class});
LintIssues lintIssues = null;
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(lintResult);
bis = new BufferedInputStream(fis);
lintIssues = (LintIssues) xstream.fromXML(bis);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
List<LintIssue> issueList = lintIssues.getIssueList();
for (LintIssue issue : issueList) {
printIssue(issue);
}
if(bis != null){
try{
bis.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void printIssue(LintIssue issue) {
System.out.println("ID= " + issue.getId() + " , severity= " + issue.getSeverity() + " , priority= " + issue.getPriority());
for (Location location : issue.getLocations()) {
printLocation(location);
}
}
private void printLocation(Location location) {
System.out.println("\t Location file=" + location.getFilename());
}
}
LintIssues クラス
//@XStreamAlias("issues")
public class LintIssues {
@XStreamImplicit(itemFieldName = "issue")
private List<LintIssue> issueList = new ArrayList<LintIssue>();
public LintIssues(List<LintIssue> issueList) {
this.issueList = issueList;
}
public List<LintIssue> getIssueList() {
return issueList;
}
}
LintIssue クラス
//@XStreamAlias("issue")
public class LintIssue {
@XStreamAlias("id")
@XStreamAsAttribute
private String id;
@XStreamAlias("severity")
@XStreamAsAttribute
private String severity;
@XStreamAlias("category")
@XStreamAsAttribute
private String category;
@XStreamAlias("priority")
@XStreamAsAttribute
private int priority;
@XStreamAlias("summary")
@XStreamAsAttribute
private String summary;
@XStreamAlias("explanation")
@XStreamAsAttribute
private String explanation;
@XStreamAlias("message")
@XStreamAsAttribute
private String message;
@XStreamAlias("errorLine1")
@XStreamAsAttribute
private String errorLine1;
@XStreamAlias("errorLine2")
@XStreamAsAttribute
private String errorLine2;
@XStreamImplicit(itemFieldName = "location")
private List<Location> locations = new ArrayList<Location>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSeverity() {
return severity;
}
public void setSeverity(String severity) {
this.severity = severity;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getExplanation() {
return explanation;
}
public void setExplanation(String explanation) {
this.explanation = explanation;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getErrorLine1() {
return errorLine1;
}
public void setErrorLine1(String errorLine1) {
this.errorLine1 = errorLine1;
}
public String getErrorLine2() {
return errorLine2;
}
public void setErrorLine2(String errorLine2) {
this.errorLine2 = errorLine2;
}
public List<Location> getLocations() {
return locations == null ? new ArrayList<Location>() : locations;
}
public void setLocations(List<Location> locations) {
this.locations = locations;
}
}
ロケーションクラス
//@XStreamAlias("location")
public class Location implements Serializable {
private static final long serialVersionUID = 1128640353127613495L;
@XStreamAlias("file")
@XStreamAsAttribute
private String filename;
@XStreamAlias("line")
@XStreamAsAttribute
private int lineNumber;
@XStreamAlias("column")
@XStreamAsAttribute
private int column;
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public int getLineNumber() {
return lineNumber;
}
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
}