Skip to content

Commit f39c001

Browse files
committed
[MPMD-304] - maven-pmd-plugin should be toolchains-aware
Separates the execution of PMD and CPD from PmdReport/CpdReport into separate classes PmdExecutor/CpdExecutor under package o.a.m.p.pmd.exec. All the necessary plugin properties/parameters are handed over as PmdRequest/CpdRequest. If a toolchain is in use, then PmdExecutor/CpdExecutor is called in a forked JVM. PmdRequest/CpdRequest is serialized/deserialized. Without a toolchain, PmdExecutor/CpdExecutor is directly called. The result is provided for reporting via PmdResult/CpdResult. These classes are just wrappers around the files `target/pmd.xml` and `target/cpd.xml` which are always created. Basically, PMD serializes the results into these XML files and m-pmd-p picks it up from there (like the check goal). The public method `PmdReport.getPMDConfiguration()` is gone, since PMDConfiguration is created now by PmdExecutor and is not exposed anymore. There is no direct replacement for this method. PmdReportGenerator and CpdReportGenerator now work with the classes generated by modello (in other words, they work now with the XML format of PMD) instead of using PMD classes directly. This further decouples the plugin from PMD. Closes #31
1 parent 597d4cb commit f39c001

32 files changed

+2610
-859
lines changed

pom.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,18 @@ under the License.
132132
<artifactId>maven-common-artifact-filters</artifactId>
133133
<version>3.1.0</version>
134134
</dependency>
135+
<dependency>
136+
<groupId>org.apache.maven</groupId>
137+
<artifactId>maven-embedder</artifactId>
138+
<version>3.1.0</version>
139+
<scope>provided</scope>
140+
</dependency>
135141

136142
<!-- pmd -->
137143
<dependency>
138144
<groupId>org.apache.commons</groupId>
139145
<artifactId>commons-lang3</artifactId>
140-
<version>3.7</version>
146+
<version>3.8.1</version>
141147
</dependency>
142148
<dependency>
143149
<groupId>net.sourceforge.pmd</groupId>
@@ -200,6 +206,11 @@ under the License.
200206
<artifactId>maven-reporting-impl</artifactId>
201207
<version>3.0.0</version>
202208
</dependency>
209+
<dependency>
210+
<groupId>org.apache.maven.shared</groupId>
211+
<artifactId>maven-shared-utils</artifactId>
212+
<version>3.2.1</version>
213+
</dependency>
203214

204215
<!-- plexus -->
205216
<dependency>
@@ -244,6 +255,12 @@ under the License.
244255
<version>2.5</version>
245256
<!-- scope>test</scope> Required by PMD transitively. -->
246257
</dependency>
258+
<dependency>
259+
<groupId>org.slf4j</groupId>
260+
<artifactId>slf4j-simple</artifactId>
261+
<version>1.7.5</version>
262+
<scope>test</scope>
263+
</dependency>
247264
</dependencies>
248265

249266
<build>
@@ -342,6 +359,7 @@ under the License.
342359
<artifactId>maven-invoker-plugin</artifactId>
343360
<configuration>
344361
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
362+
<debug>false</debug>
345363
<goals>
346364
<goal>clean</goal>
347365
<goal>site</goal>

src/it/MPMD-244-logging/invoker.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717

1818
invoker.goals = clean pmd:check
1919
invoker.maven.version = 3.1.0+
20+
invoker.debug = true
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
invoker.java.version = 1.7+
19+
20+
# available toolchains under linux:
21+
# https://github.com/apache/infrastructure-p6/blob/production/modules/build_nodes/files/toolchains.xml
22+
# the jdk toolchain "11:oracle" is selected in pom.xml
23+
24+
# since the toolchains are only configured under linux slaves
25+
# we don't use invoker selections here, but selector.groovy
26+
#invoker.toolchain.jdk.version = 11
27+
#invoker.toolchain.jdk.vendor = oracle
28+
29+
# the file toolchains.xml will be created by selector.groovy
30+
# - for linux, ${user.home}/.m2/toolchains.xml will be copied
31+
# - for windows, a new file will be created using toolchains.windows.xml, see selector.groovy
32+
invoker.goals = clean verify --toolchains toolchains.xml
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!--
4+
Licensed to the Apache Software Foundation (ASF) under one
5+
or more contributor license agreements. See the NOTICE file
6+
distributed with this work for additional information
7+
regarding copyright ownership. The ASF licenses this file
8+
to you under the Apache License, Version 2.0 (the
9+
"License"); you may not use this file except in compliance
10+
with the License. You may obtain a copy of the License at
11+
12+
http://www.apache.org/licenses/LICENSE-2.0
13+
14+
Unless required by applicable law or agreed to in writing,
15+
software distributed under the License is distributed on an
16+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
KIND, either express or implied. See the License for the
18+
specific language governing permissions and limitations
19+
under the License.
20+
-->
21+
22+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
23+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
24+
<modelVersion>4.0.0</modelVersion>
25+
<groupId>org.apache.maven.plugins.pmd.it</groupId>
26+
<artifactId>MPMD-304-toolchain-support</artifactId>
27+
<version>1.0-SNAPSHOT</version>
28+
29+
<properties>
30+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
31+
<java.version>11</java.version>
32+
</properties>
33+
34+
<build>
35+
<pluginManagement>
36+
<plugins>
37+
<plugin>
38+
<groupId>org.apache.maven.plugins</groupId>
39+
<artifactId>maven-compiler-plugin</artifactId>
40+
<version>3.8.0</version>
41+
<configuration>
42+
<target>${java.version}</target>
43+
<source>${java.version}</source>
44+
</configuration>
45+
</plugin>
46+
</plugins>
47+
</pluginManagement>
48+
<plugins>
49+
<plugin>
50+
<groupId>org.apache.maven.plugins</groupId>
51+
<artifactId>maven-pmd-plugin</artifactId>
52+
<version>@project.version@</version>
53+
<configuration>
54+
<failOnViolation>false</failOnViolation>
55+
<printFailingErrors>true</printFailingErrors>
56+
<targetJdk>${java.version}</targetJdk>
57+
<sourceEncoding>UTF-8</sourceEncoding>
58+
<minimumTokens>10</minimumTokens>
59+
</configuration>
60+
<executions>
61+
<execution>
62+
<id>default</id>
63+
<phase>verify</phase>
64+
<goals>
65+
<goal>check</goal>
66+
<goal>cpd-check</goal>
67+
</goals>
68+
</execution>
69+
</executions>
70+
</plugin>
71+
<plugin>
72+
<groupId>org.apache.maven.plugins</groupId>
73+
<artifactId>maven-toolchains-plugin</artifactId>
74+
<version>3.0.0</version>
75+
<executions>
76+
<execution>
77+
<goals>
78+
<goal>toolchain</goal>
79+
</goals>
80+
</execution>
81+
</executions>
82+
<configuration>
83+
<toolchains>
84+
<jdk>
85+
<version>${java.version}</version>
86+
<vendor>oracle</vendor>
87+
</jdk>
88+
</toolchains>
89+
</configuration>
90+
</plugin>
91+
</plugins>
92+
</build>
93+
</project>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
File testToolchains = new File( basedir, 'toolchains.xml' )
21+
22+
File userToolchains = new File( System.getProperty( 'user.home' ), '.m2/toolchains.xml' )
23+
if ( userToolchains.exists() )
24+
{
25+
System.out.println( "INFO: Copying ${userToolchains.absolutePath} to ${testToolchains.absolutePath}" )
26+
testToolchains.text = userToolchains.text
27+
}
28+
else
29+
{
30+
System.out.println( "WARNING: File ${userToolchains.absolutePath} not found" )
31+
if ( System.getProperty( 'os.name' ).startsWith( 'Windows' ) )
32+
{
33+
String jdk11Windows = 'f:\\jenkins\\tools\\java\\latest11'
34+
File windowsToolchains = new File( basedir, 'toolchains.windows.xml' )
35+
System.out.println( "INFO: Creating ${testToolchains.absolutePath} with jdk:11:oracle=${jdk11Windows}" )
36+
37+
String placeholder = '@jdk.home@'
38+
String replacement = jdk11Windows
39+
// extra escaping of backslashes in the path for Windows
40+
replacement = replacement.replaceAll("\\\\", "\\\\\\\\")
41+
testToolchains.text = windowsToolchains.text.replaceAll( placeholder, replacement )
42+
System.out.println( "Replaced '${placeholder}' with '${replacement}' in '${testToolchains.absolutePath}'." )
43+
}
44+
}
45+
46+
if ( testToolchains.exists() )
47+
{
48+
def toolchains = new XmlParser().parseText( testToolchains.text )
49+
def result = toolchains.children().find { toolchain ->
50+
toolchain.type.text() == 'jdk' &&
51+
toolchain.provides.version.text() == '11' &&
52+
toolchain.provides.vendor.text() == 'oracle'
53+
}
54+
if ( !result )
55+
{
56+
System.out.println( "WARNING: No jdk toolchain for 11:oracle found" )
57+
return false
58+
}
59+
60+
System.out.println( "INFO: Found toolchain: ${result}" )
61+
return true
62+
}
63+
64+
System.out.println( "WARNING: Skipping integration test due to missing toolchain" )
65+
return false
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package sample;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
public class Name extends Thread
23+
{
24+
private final String name;
25+
26+
public Name( String name )
27+
{
28+
this.name = name;
29+
}
30+
31+
@Override
32+
public String toString()
33+
{
34+
return name;
35+
}
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package sample;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
public class Name2 extends Thread
23+
{
24+
private final String name;
25+
26+
public Name2( String name )
27+
{
28+
this.name = name;
29+
}
30+
31+
@Override
32+
public String toString()
33+
{
34+
return name;
35+
}
36+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package sample;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
import java.util.function.Function;
22+
23+
// this class trigger PMD rule category/java/codestyle.xml/ExtendsObject
24+
public class Sample extends Object
25+
{
26+
public static void main( String ... args )
27+
{
28+
new Sample();
29+
}
30+
31+
public Sample()
32+
{
33+
// this triggers category/java/multithreading.xml/DontCallThreadRun
34+
// it only works, if the auxclass path could be loaded,
35+
// by using the correct jdk toolchain
36+
new Name( "foo" ).run();
37+
Name name = getName( new Name( "World" ) );
38+
Function<Name, String> greeter = (var n) -> "Hello " + n;
39+
System.out.println( greeter.apply( name ) );
40+
}
41+
42+
private Name getName( Name name )
43+
{
44+
return new Name( name.toString() + "!" );
45+
}
46+
}

0 commit comments

Comments
 (0)