Skip to content

Commit

Permalink
[MPMD-304] - maven-pmd-plugin should be toolchains-aware
Browse files Browse the repository at this point in the history
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
  • Loading branch information
adangel committed Oct 16, 2020
1 parent 597d4cb commit f39c001
Show file tree
Hide file tree
Showing 32 changed files with 2,610 additions and 859 deletions.
20 changes: 19 additions & 1 deletion pom.xml
Expand Up @@ -132,12 +132,18 @@ under the License.
<artifactId>maven-common-artifact-filters</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>

<!-- pmd -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
Expand Down Expand Up @@ -200,6 +206,11 @@ under the License.
<artifactId>maven-reporting-impl</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-shared-utils</artifactId>
<version>3.2.1</version>
</dependency>

<!-- plexus -->
<dependency>
Expand Down Expand Up @@ -244,6 +255,12 @@ under the License.
<version>2.5</version>
<!-- scope>test</scope> Required by PMD transitively. -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -342,6 +359,7 @@ under the License.
<artifactId>maven-invoker-plugin</artifactId>
<configuration>
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
<debug>false</debug>
<goals>
<goal>clean</goal>
<goal>site</goal>
Expand Down
1 change: 1 addition & 0 deletions src/it/MPMD-244-logging/invoker.properties
Expand Up @@ -17,3 +17,4 @@

invoker.goals = clean pmd:check
invoker.maven.version = 3.1.0+
invoker.debug = true
32 changes: 32 additions & 0 deletions src/it/MPMD-304-toolchain-support/invoker.properties
@@ -0,0 +1,32 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

invoker.java.version = 1.7+

# available toolchains under linux:
# https://github.com/apache/infrastructure-p6/blob/production/modules/build_nodes/files/toolchains.xml
# the jdk toolchain "11:oracle" is selected in pom.xml

# since the toolchains are only configured under linux slaves
# we don't use invoker selections here, but selector.groovy
#invoker.toolchain.jdk.version = 11
#invoker.toolchain.jdk.vendor = oracle

# the file toolchains.xml will be created by selector.groovy
# - for linux, ${user.home}/.m2/toolchains.xml will be copied
# - for windows, a new file will be created using toolchains.windows.xml, see selector.groovy
invoker.goals = clean verify --toolchains toolchains.xml
93 changes: 93 additions & 0 deletions src/it/MPMD-304-toolchain-support/pom.xml
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->

<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>org.apache.maven.plugins.pmd.it</groupId>
<artifactId>MPMD-304-toolchain-support</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
</properties>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<target>${java.version}</target>
<source>${java.version}</source>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<failOnViolation>false</failOnViolation>
<printFailingErrors>true</printFailingErrors>
<targetJdk>${java.version}</targetJdk>
<sourceEncoding>UTF-8</sourceEncoding>
<minimumTokens>10</minimumTokens>
</configuration>
<executions>
<execution>
<id>default</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
<goal>cpd-check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
<configuration>
<toolchains>
<jdk>
<version>${java.version}</version>
<vendor>oracle</vendor>
</jdk>
</toolchains>
</configuration>
</plugin>
</plugins>
</build>
</project>
65 changes: 65 additions & 0 deletions src/it/MPMD-304-toolchain-support/selector.groovy
@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

File testToolchains = new File( basedir, 'toolchains.xml' )

File userToolchains = new File( System.getProperty( 'user.home' ), '.m2/toolchains.xml' )
if ( userToolchains.exists() )
{
System.out.println( "INFO: Copying ${userToolchains.absolutePath} to ${testToolchains.absolutePath}" )
testToolchains.text = userToolchains.text
}
else
{
System.out.println( "WARNING: File ${userToolchains.absolutePath} not found" )
if ( System.getProperty( 'os.name' ).startsWith( 'Windows' ) )
{
String jdk11Windows = 'f:\\jenkins\\tools\\java\\latest11'
File windowsToolchains = new File( basedir, 'toolchains.windows.xml' )
System.out.println( "INFO: Creating ${testToolchains.absolutePath} with jdk:11:oracle=${jdk11Windows}" )

String placeholder = '@jdk.home@'
String replacement = jdk11Windows
// extra escaping of backslashes in the path for Windows
replacement = replacement.replaceAll("\\\\", "\\\\\\\\")
testToolchains.text = windowsToolchains.text.replaceAll( placeholder, replacement )
System.out.println( "Replaced '${placeholder}' with '${replacement}' in '${testToolchains.absolutePath}'." )
}
}

if ( testToolchains.exists() )
{
def toolchains = new XmlParser().parseText( testToolchains.text )
def result = toolchains.children().find { toolchain ->
toolchain.type.text() == 'jdk' &&
toolchain.provides.version.text() == '11' &&
toolchain.provides.vendor.text() == 'oracle'
}
if ( !result )
{
System.out.println( "WARNING: No jdk toolchain for 11:oracle found" )
return false
}

System.out.println( "INFO: Found toolchain: ${result}" )
return true
}

System.out.println( "WARNING: Skipping integration test due to missing toolchain" )
return false
36 changes: 36 additions & 0 deletions src/it/MPMD-304-toolchain-support/src/main/java/sample/Name.java
@@ -0,0 +1,36 @@
package sample;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

public class Name extends Thread
{
private final String name;

public Name( String name )
{
this.name = name;
}

@Override
public String toString()
{
return name;
}
}
36 changes: 36 additions & 0 deletions src/it/MPMD-304-toolchain-support/src/main/java/sample/Name2.java
@@ -0,0 +1,36 @@
package sample;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

public class Name2 extends Thread
{
private final String name;

public Name2( String name )
{
this.name = name;
}

@Override
public String toString()
{
return name;
}
}
46 changes: 46 additions & 0 deletions src/it/MPMD-304-toolchain-support/src/main/java/sample/Sample.java
@@ -0,0 +1,46 @@
package sample;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.function.Function;

// this class trigger PMD rule category/java/codestyle.xml/ExtendsObject
public class Sample extends Object
{
public static void main( String ... args )
{
new Sample();
}

public Sample()
{
// this triggers category/java/multithreading.xml/DontCallThreadRun
// it only works, if the auxclass path could be loaded,
// by using the correct jdk toolchain
new Name( "foo" ).run();
Name name = getName( new Name( "World" ) );
Function<Name, String> greeter = (var n) -> "Hello " + n;
System.out.println( greeter.apply( name ) );
}

private Name getName( Name name )
{
return new Name( name.toString() + "!" );
}
}

0 comments on commit f39c001

Please sign in to comment.