In the Eclipe PMD plugin, can I reference the standard ruleset files? - java

I would like my eclipse PMD plugin configuration to access the same standard ruleset files as the maven-pmd-plugin.
You can configure the maven pmd plugin to use a custom set of rule sets like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>2.5</version>
<configuration>
<rulesets>
<!-- Two rule sets that come bundled with PMD -->
<ruleset>/rulesets/braces.xml</ruleset>
<ruleset>/rulesets/naming.xml</ruleset>
<!-- Custom local file system rule set -->
<ruleset>d:\rulesets\strings.xml</ruleset>
<!-- Custom remote rule set accessed via a URL -->
<ruleset>http://localhost/design.xml</ruleset>
</rulesets>
</configuration>
</plugin>
but in the eclipse plugin you can only switch on / turn off individual rules or specify a single ruleset file. Is there perhaps a way that ruleset file can include several others? Or do I have to aggregate that file automatically from the rulesets I want to use?

You can include other rulesets in a PMD ruleset file, e.g.
<ruleset ...>
...
<rule ref="rulesets/basic.xml"/>
...
<rule ref="rulesets/strings.xml">
<exclude name="AvoidDuplicateLiterals"/>
</rule>
...
</ruleset>
This is actually an excerpt from our own ruleset file, so it is proven to work :-)
As you can see, you can exclude/include individual rules from your ruleset, or even reconfigure them. One caveat: you must not mix rules for different languages in a single ruleset. I.e. in our case, we had to create separate rulesets for Java and JSP.
I learned the tricks myself from this page.

Related

PMD custom ruleset - Maybe you mispelled a rule name?

I am trying to integrate pmd into my project. But I am getting following error
java.lang.IllegalArgumentException: No rules found. Maybe you mispelled a rule name?
The pom.xml entry is as follows -
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.7</version>
<configuration>
<linkXRef>false</linkXRef>
<rulesets>             
<ruleset>
pmdruleset.xml
</ruleset>
</rulesets>
</configuration>
</plugin>
</plugins>
</reporting>
The custom rule set file contains following -
<?xml version="1.0"?>
<ruleset name="Controversial"
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>
<rule ref="rulesets/java/errorprone.xml/NullAssignment"/>
</description>
</ruleset>
I am unable to understand what is wrong. Can someone help!
#eclipse-pmd is right, the rule tag needs to be a child of the ruleset tag.
Additionally, the rule you are trying to use (NullAssignment), is not in the ruleset errorprone, but in controversial. With PMD 6, the rules have additionally been organized into categories and is now in category "errorprone". More on this will follow.
maven-pmd-plugin 3.7 / PMD 5.5.1
You are using maven-pmd-plugin version 3.7 -> this means, you automatically use an old PMD version (version 5.5.1 to be precise). For this version, your ruleset should look like the following:
<?xml version="1.0"?>
<ruleset name="Custom 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>
Custom Ruleset
</description>
<rule ref="rulesets/java/controversial.xml/NullAssignment"/>
</ruleset>
Documentation for PMD 5.5.1 is available at: https://pmd.github.io/pmd-5.5.1/pmd-java/rules/java/controversial.html#NullAssignment
maven-pmd-plugin 3.9.0 / PMD 6.0.1
If you switch to the latest maven-pmd-plugin version 3.9.0, you'll automatically use PMD 6.0.1 and benefit from the latest bugfixes. You can continue to use the ruleset from above, however you'll see a deprecation notice, since we moved the rule. To get rid of this warning, use the following rule reference:
<rule ref="category/java/errorprone.xml/NullAssignment" />
Documentation for PMD 6.0.1 is available at: https://pmd.github.io/pmd-6.0.1/pmd_rules_java_errorprone.html#nullassignment
Documentation about rulesets is here: https://pmd.github.io/pmd-6.0.1/pmd_userdocs_understanding_rulesets.html

Testing with Arquillian, how to share Arquillian.xml?

How can the Arquillian configuration file Arquillian.xml be shared between projects and team members?
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="jbossas-managed-wildfly-8" default="true">
<configuration>
<property name="jbossHome">C:\test\wildfly-8.1.0.Final</property>
<property name="javaVmArguments">-Djboss.socket.binding.port-offset=2 -Xmx512m -XX:MaxPermSize=128m</property>
<property name="managementPort">9992</property>
</configuration>
</container>
The problem is this points to specific locations on the the disk, and different team members use Wildfly in different locations.
In addition we must duplicate Arquillian.xml for each project that uses it.
We use Arquillian for Maven testing (which could inject the values) and JUnit tests within Eclipse (which cannot inject them).
Any ideas how to do this?
Since there is already Maven support and structure then you can make use of Maven properties and replace of place holder values. It is simple
I guess your Arquillian.xml is under src/test/resources/arquillian.xml right? Then you can replace the absolute values with properties.
<configuration>
<property name="jbossHome">${jboss.home}</property>
</configuration>
The above property can be either defined in the properties section of your pom or can be overridden during mvn executuon using -Djboss.home=C:\myPath
In order though this thing to work, you want Maven automatically for each developer when is about to package arquillian.xml to replace this place-holder ${jboss.home} with a value, that we have either defined on top in the properties section or we have passed it from the command line. This is done through the resource filtering functionality
<build>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
<testResources>
</build>
See the simple examples here

Automatic verification of JavaDoc with Maven

During refactoring it happens frequently that JavaDoc gets out-of-date. It describes method arguments which are not present any more or some new ones are missing, to give examples.
It would be fine, if there is a Maven-plugin which automatically checks the existing JavaDoc and stops the build if there are some kind of "JavaDoc-violations".
I've seen the Maven-JavaDoc-Plugin and maven-doccheck, but both seem only to be able fix existing JavaDoc automatically in case of violations instead of bailing some error or warning.
Does anyone know how if there is some Maven-plugin like this and how to archive this?
As far as I know this is currently not possible with the maven-javadoc-plugin. There is the javadoc:fix mojo for the JavaDoc plugin, but this automatically fixes problems.
I recently created a JIRA entry for this problem: MJAVADOC-374 (which is acutally a duplicate of MJAVADOC-314).
Update:
You can use Checkstyle to verify correct JavaDoc. The configuration options are described here. Use the maven-checkstyle-plugin and the check-Mojo to integrate this into your maven build.
An example maven configuration could look like this:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.15</version>
<configuration>
<logViolationsToConsole>true</logViolationsToConsole>
<checkstyleRules>
<module name="JavadocMethod">
<property name="scope" value="public"/>
<property name="allowUndeclaredRTE" value="true"/>
<property name="allowMissingParamTags" value="false"/>
</module>
</checkstyleRules>
</configuration>
</plugin>
</plugins>
</build>
...
</project>

Supporting i18n in GWT

Till now, our web application supports only English. Now we have to provide support for Italian as well. There is GWT module for some functionality. To support the Italian language I have added below line in the file "APP_Module.gwt.xml"
<extend-property name="locale" values="it"/>
I have also placed "XXX_it.properties" file under the source code where the properties file for en is kept.
Setting the locale in the jsp by following line:
<meta name="gwt:property" content="locale=${locale}">
Now, the issue is how to compile the code. I am debugging the application but it is not hitting the client code of GWT presented under WEB-INF/src.
I am very new to GWT. Please suggest how can I compile the code or there is no need of compilation. It will automatically take the changes done in "APP_Module.gwt.xml" and there is some other issue. How can I see logs of GWT?
To add support for locales to GWT application, you need to do the following in your xxx.gwt.xml:
under <module> add this to include the support:
<inherits name="com.google.gwt.i18n.I18N" />
and this to configure it:
<extend-property name="locale" values="en,it"/>
<set-property-fallback name="locale" value="en"/>
Add all your property files under some package like this:
src/main/resources/foo/bar/client/i18n/MyMessages.properties
src/main/resources/foo/bar/client/i18n/MyMessages_it.properties
Then you need to tell GWT to compile them into classes. This is example from a pom.xml file (if you don't use maven, you will have to use a different way, but you still need to configure it).
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.3.1.google</version>
<executions>
<execution>
<goals>
<goal>i18n</goal>
<goal>generateAsync</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<i18nMessagesBundles>
<resourceBundle>foo.bar.client.i18n.MyMessages</resourceBundle>
</i18nMessagesBundles>
</configuration>
</plugin>
Then you need to recompile the code. In maven mvn compile. And that's all, you will have your messages in generated sources folder ready to use.
For seeing the logs of gwt you can use gradlew gwt also you can use it to compile the code too.

Maven: Usage of external libraries for integration test

Currently, I set up an integration test suite. The base is a Maven project with several modules which are dependent to each other to setup a database, to put some data into it and to run tests on it, before wrapping everything up. Additionally, I have modules with some utilities and test data in there.
The first step (not mentioned above) is the copy of a zipped image which includes a lot of JAR files which make up the software suite to be tested. Unfortunately, the software is not build by Maven, but by Ant, so I can not find the stuff in an Artifactory or something similar.
My problem is now, that I copy and unzip the image with an integration test method, but I do not know, how I can add the JAR files to the Maven classpath. All other modules need to compile and run against the jars extracted from the ZIP file.
How can I add the JARs to the Maven class path for later compiling and test runs? The destination of the ZIP content is always the same directory. Unfortunately, the names of the JARs contain version information (build numbers) which change. So an easy usage of system and the tag is not working so easily. A path entry like ${package.path}/lib/*/.jar would be great. Is there a plugin, maybe?
Or does anyone have a better idea to setup an integration test against prebuild JARs?
Create a single jar from all of your dependencies, everything in ${package.path}/lib/*/.jar.
You could use an ant task to create this jar, either before you run maven, or as part of your maven build.
To merge your jars, you can use the Ant Jar Task (see section Merging Archives). From there:
<jar destfile="build/main/checksites.jar">
<fileset dir="build/main/classes"/>
<restrict>
<name name="**/*.class"/>
<archives>
<zips>
<fileset dir="lib/main" includes="**/*.jar"/>
</zips>
</archives>
</restrict>
</jar>
This creates a jar file which embeds all the classes from all the jars in lib/main.
You can then use the system scope which points at this jar as normal in maven. Note: if you create the jar in maven (via ant), then you should create the jar in target, so that it gets cleaned correctly.
To use an ant build file from maven, you can use the maven antrun plugin, similarly to:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<property name="local.project.artifact.name" value="${project.build.finalName}" />
<property name="local.distribution.artifact.name" value="${local.project.artifact.name}-distribution" />
<property name="local.distribution.artifact.file" value="${project.build.directory}/${local.distribution.artifact.name}.zip" />
<ant antfile="build-deploy.xml" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
This runs the ant build file build-deploy.xml in the package phase. The modifications necessary for your system are left as an exercise for the reader :-).

Categories