[MPMD-307] - NPE when using custom rule
diff --git a/src/main/java/org/apache/maven/plugins/pmd/PmdReportGenerator.java b/src/main/java/org/apache/maven/plugins/pmd/PmdReportGenerator.java
index f1dae2a..a094363 100644
--- a/src/main/java/org/apache/maven/plugins/pmd/PmdReportGenerator.java
+++ b/src/main/java/org/apache/maven/plugins/pmd/PmdReportGenerator.java
@@ -183,13 +183,28 @@
         sink.section_( level );
     }
 
+    private void addRuleName( Violation ruleViolation )
+    {
+        boolean hasUrl = StringUtils.isNotBlank( ruleViolation.getExternalInfoUrl() );
+
+        if ( hasUrl )
+        {
+            sink.link( ruleViolation.getExternalInfoUrl() );
+        }
+
+        sink.text( ruleViolation.getRule() );
+
+        if ( hasUrl )
+        {
+            sink.link_();
+        }
+    }
+
     private void processSingleRuleViolation( Violation ruleViolation, PmdFileInfo fileInfo )
     {
         sink.tableRow();
         sink.tableCell();
-        sink.link( ruleViolation.getExternalInfoUrl() );
-        sink.text( ruleViolation.getRule() );
-        sink.link_();
+        addRuleName( ruleViolation );
         sink.tableCell_();
         sink.tableCell();
         sink.text( ruleViolation.getText() );
diff --git a/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java b/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java
index 4718d87..8a4fc0b 100644
--- a/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java
+++ b/src/test/java/org/apache/maven/plugins/pmd/PmdReportTest.java
@@ -664,4 +664,30 @@
         final Renderer renderer = PmdExecutor.createRenderer( "net.sourceforge.pmd.renderers.CodeClimateRenderer", "UTF-8" );
         assertNotNull(renderer);
     }
+
+    public void testPmdReportCustomRulesNoExternalInfoUrl()
+            throws Exception
+    {
+        FileUtils.copyDirectoryStructure( new File( getBasedir(),
+                                                    "src/test/resources/unit/default-configuration/jxr-files" ),
+                                          new File( getBasedir(), "target/test/unit/default-configuration/target/site" ) );
+
+        File testPom =
+            new File( getBasedir(),
+                      "src/test/resources/unit/default-configuration/pmd-report-custom-rules.xml" );
+        PmdReport mojo = (PmdReport) lookupMojo( "pmd", testPom );
+        mojo.execute();
+
+        File generatedFile = new File( getBasedir(), "target/test/unit/default-configuration/target/site/pmd.html" );
+        renderer( mojo, generatedFile );
+        assertTrue( FileUtils.fileExists( generatedFile.getAbsolutePath() ) );
+
+        String str = readFile( generatedFile );
+
+        // custom rule without link
+        assertEquals( 2, StringUtils.countMatches( str, "<td>CustomRule</td>" ) );
+        // standard rule with link
+        assertEquals( 4, StringUtils.countMatches( str, "\">UnusedPrivateField</a></td>" ) );
+    }
+
 }
diff --git a/src/test/resources/unit/default-configuration/pmd-report-custom-rules.xml b/src/test/resources/unit/default-configuration/pmd-report-custom-rules.xml
new file mode 100644
index 0000000..04c2c55
--- /dev/null
+++ b/src/test/resources/unit/default-configuration/pmd-report-custom-rules.xml
@@ -0,0 +1,62 @@
+<!--
+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>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>def.configuration</groupId>
+  <artifactId>default-configuration</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <inceptionYear>2006</inceptionYear>
+  <name>Maven PMD Plugin Default Configuration Test</name>
+  <url>http://maven.apache.org</url>
+  <build>
+    <finalName>default-configuration</finalName>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <configuration>
+          <project implementation="org.apache.maven.plugins.pmd.stubs.DefaultConfigurationMavenProjectStub"/>
+          <outputDirectory>${basedir}/target/test/unit/default-configuration/target/site</outputDirectory>
+          <targetDirectory>${basedir}/target/test/unit/default-configuration/target</targetDirectory>
+          <rulesetsTargetDirectory>${basedir}/target/test/unit/default-configuration/target/pmd/rulesets</rulesetsTargetDirectory>
+          <rulesets>
+            <ruleset>${basedir}/src/test/resources/unit/default-configuration/rulesets/custom-rules.xml</ruleset>
+          </rulesets>
+          <format>xml</format>
+          <linkXRef>true</linkXRef>
+          <xrefLocation>${basedir}/target/test/unit/default-configuration/target/site/xref</xrefLocation>
+          <sourceEncoding>UTF-8</sourceEncoding>
+          <compileSourceRoots>
+            <compileSourceRoot>${basedir}/src/test/resources/unit/default-configuration/</compileSourceRoot>
+          </compileSourceRoots>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>
diff --git a/src/test/resources/unit/default-configuration/rulesets/custom-rules.xml b/src/test/resources/unit/default-configuration/rulesets/custom-rules.xml
new file mode 100644
index 0000000..4946c53
--- /dev/null
+++ b/src/test/resources/unit/default-configuration/rulesets/custom-rules.xml
@@ -0,0 +1,47 @@
+<?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.
+-->
+<ruleset name="Custom PMD Rule Ruleset"
+    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
+
+    <description>
+        A ruleset with a custom rule without "externalInfoUrl".
+    </description>
+
+    <rule name="CustomRule"
+          language="java"
+          message="custom rule test"
+          class="net.sourceforge.pmd.lang.rule.XPathRule">
+        <description>custom xpath rule test</description>
+        <priority>1</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[@SimpleName = 'App']
+]]>
+                </value>
+            </property>
+        </properties>
+    </rule>
+
+    <rule ref="category/java/bestpractices.xml/UnusedPrivateField" />
+</ruleset>