Is there any PMD or Checkstyle rule available that could help me to prohibit usage of some certain classes in Java code?
In my case I'd like to ban all of the following in all possible contexts:
org.apache.commons.lang3.CharEncoding
org.apache.commons.lang.CharEncoding
org.apache.commons.codec.CharEncoding
I've found IllegalImport check, but it's about packages, not particular classes.
For PMD you can write rule like this:
<rule name="Prohibited classes"
language="java"
message="Avoid using these classes."
class="net.sourceforge.pmd.lang.rule.XPathRule" >
<description>
Avoid using these classes, there are better alternatives.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//Name[pmd-java:typeIs('org.apache.commons.lang3.CharEncoding')] |
//Name[pmd-java:typeIs('org.apache.commons.lang.CharEncoding')] |
//Name[pmd-java:typeIs('org.apache.commons.codec.CharEncoding')]
]]>
</value>
</property>
</properties>
</rule>
Or //Name[starts-with(#Image, 'com.sun.')] to prohibit package import.
You can try to use these pmd extensions to blacklist classes and methods: https://github.com/LiveRamp/pmd_extensions
Related
I want to have a pmd rule for my java project which will disallow field injections in Spring(want to use injection by constructor instead). is there any pmd rule for it, or can I create some to have it in my code analysis?
To not allow this:
#Autorired
private Object object;
thanks!
You could create an XPath rule with the following expression:
//Annotation
[pmd-java:typeIs('org.springframework.beans.factory.annotation.Autowired')]
[../FieldDeclaration]
To add this to your ruleset XML, see here:
<rule name="todo"
language="java"
message="todo."
class="net.sourceforge.pmd.lang.rule.XPathRule" >
<description>
TODO
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//Annotation
[pmd-java:typeIs('org.springframework.beans.factory.annotation.Autowired')]
[../FieldDeclaration]
]]>
</value>
</property>
</properties>
</rule>
I am developing a JPA application which requires to be able to access different schemas on the same database (i.e. DB2/Oracle). I want all of my entities to be registered in the persistence.xml file (<class>) and be able to define which ones belong to certain schemas.
I know it is possible to use java annotations, however this is a product which will need the end user to configure that accordingly (hence why I want to be able to achieve this in an xml file).
Currently I have found an example like this:
orm.xml
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">
<persistence-unit-metadata>
<persistence-unit-defaults>
<schema>SECURITY</schema>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="jpa.sample.plain">
<mapping-file>custom-orm.xml</mapping-file>
<class>com.reds.model.Role</class>
<class>com.reds.model.User</class>
<properties>
<property name="javax.persistence.target-database" value="PostgreSQL" />
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://127.0.0.1:5432/security" />
<property name="javax.persistence.jdbc.user" value="user" />
<property name="javax.persistence.jdbc.password" value="password" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="none" />
<property name="eclipselink.weaving" value="false" />
<!-- <property name="eclipselink.ddl-generation.output-mode"
value="database" /> -->
<property name="eclipselink.logging.level" value="INFO"/>
</properties>
</persistence-unit>
</persistence>
In the above files, from my understanding the schema "SECURITY" is set on the persistence unit that includes the orm.xml mapping file (makes it the default which an annotation can change?). But this makes the schema be implicitly "SECURITY" for both classes listed in persistence.xml.
Contrary to the above I need:
A way to list the schema on a subset of classes in a persistence unit in an efficient way (unless if the only way is to do the entity mappings manually in the orm.xml which is something I wish to avoid and the end user would too)
Keep this away from vendor specific xml files or java implementations if possible (keep to JPA standard)
Side question: Would this allow a JPQL query to go through transparently for 2 entities with different schemas?
Details of project:
Hibernate 5.1, JPA 2.1
DB2/Oracle
EDIT:
I found this link which helped me set up my orm.xml: https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/xml-overriding.html
Posted below is the most relevant excerpt:
3.1.2. Entity level metadata
You can either define or override metadata informations on a given entity.
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappin(1)gs
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">
<package>o(2)rg.hibernate.test.annotations.reflection</package>
<entity cl(3)ass="Administration" access="PROPERTY" metadata-complete="true">
<table(4) name="tbl_admin">
<unique-constraint>
<column-name>firstname</column-name>
<column-name>lastname</column-name>
</unique-constraint>
</table>
<secon(5)dary-table name="admin2">
<primary-key-join-column name="admin_id" referenced-column-name="id"/>
<unique-constraint>
<column-name>address</column-name>
</unique-constraint>
</secondary-table>
<id-cl(6)ass class="SocialSecurityNumber"/>
<inher(7)itance strategy="JOINED"/>
<seque(8)nce-generator name="seqhilo" sequence-name="seqhilo"/>
<table(9)-generator name="table" table="tablehilo"/>
...
</entity>
<entity class="PostalAdministration">
<prima(10)ry-key-join-column name="id"/>
...
</entity>
</entity-mappings>
1 entity-mappings: entity-mappings is the root element for all XML files. You must declare the xml schema, the schema file is included in the hibernate-annotations.jar file, no internet access will be processed by Hibernate Annotations.
2 package (optional): default package used for all non qualified class names in the given deployment descriptor file.
3 entity: desribes an entity.
metadata-complete defines whether the metadata description for this element is complete or not (in other words, if annotations present at the class level should be considered or not).
An entity has to have a class attribute refering the java class the metadata applies on.
You can overrides entity name through the name attribute, if none is defined and if an #Entity.name is present, then it is used (provided that metadata complete is not set).
For metadata complete (see below) element, you can define an access (either FIELD or PROPERTY (default)). For non medatada complete element, if access is not defined, the #Id position will lead position, if access is defined, the value is used.
4 table: you can declare table properties (name, schema, catalog), if none is defined, the java annotation is used.
You can define one or several unique constraints as seen in the example
5 secondary-table: defines a secondary table very much like a regular table except that you can define the primary key / foreign key column(s) through the primary-key-join-column element. On non metadata complete, annotation secondary tables are used only if there is no secondary-table definition, annotations are ignored otherwise.
6 id-class: defines the id class in a similar way #IdClass does
7 inheritance: defines the inheritance strategy (JOINED, TABLE_PER_CLASS, SINGLE_TABLE), Available only at the root entity level
8 sequence-generator: defines a sequence generator
9 table-generator: defines a table generator
10 primary-key-join-column: defines the primary key join column for sub entities when JOINED inheritance strategy is used
No, you can't do this via the orm.xml or persistence.xml files.
That said, you can do something similar by specifying the non-standard schema in your #Table annotation on each individual persistence object.
#Entity
#Table(name = "PERSON", schema="SOME_OTHER_SCHEMA")
public class Person {
. . .
}
I want to use PMDs CommentRequired rule, but don't want it to be applied to java bean getters/setters.
Based on this answer I tried the following configuration:
<rule ref="rulesets/java/comments.xml/CommentRequired">
<properties>
<property name="violationSuppressXPath" value="./ancestor::MethodDeclaration/MethodDeclarator/NodeToken[#tokenImage='(get|is|set).*']"/>
<property name="fieldCommentRequirement" value="Ignored"/>
</properties>
</rule>
However PMD still reports that some getters in my code need a comment.
What is the correct XPath expression to suppress the rule for getters/setters and on which schema are the PMD XPath expressions based upon?
After reading the PMD XPath rule tutorial and playing around with the PMD Designer the following does work for me:
<rule ref="rulesets/java/comments.xml/CommentRequired">
<properties>
<property name="violationSuppressXPath" value="//ClassOrInterfaceBodyDeclaration/MethodDeclaration/MethodDeclarator[matches(#Image,'(get|is|set)[\p{Lu}].*') and not(FormalParameters/FormalParameter)]"/>
<property name="fieldCommentRequirement" value="Ignored"/>
</properties>
</rule>
To get a better grasp on the AST that PMD is using, one can have a look at the javadoc of it: http://pmd.sourceforge.net/pmd-5.1.0/apidocs/net/sourceforge/pmd/lang/java/ast/package-summary.html
I am using PMD plugin (version 4.0.2) for Eclipse (Eclipse Kepler Java EE). I have configured a naming rule: ShortVariable.
This works fine except for parameters like "id" and "e". I want PMD to ignore these. So I searched for a way to ignore certain parameters. I found this link (although it's for phpmd) and tried it, yet I can't seem to get it working. My config file looks like this (XML):
<?xml version="1.0"?>
<ruleset name="My PMD 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>
My PMD
</description>
<rule ref="rulesets/java/naming.xml/ShortVariable">
<property name="exceptions" value="id" />
</rule>
</ruleset>
When I try to import this ruleset using the eclipse plugin, it shows no possible rules to import.
Any ideas?
I found a solution to my problem here.
The resulting xml looks like this:
<?xml version="1.0"?>
<ruleset name="My PMD 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>
My PMD
</description>
<rule ref="rulesets/java/naming.xml/ShortVariable">
<properties>
<property name="xpath">
<value>
//VariableDeclaratorId[(string-length(#Image) < 3) and (not (#Image='id'))]
[not(ancestor::ForInit)]
[not((ancestor::FormalParameter) and (ancestor::TryStatement))]
</value>
</property>
</properties>
</rule>
</ruleset>
To be able to ignore more variable names, repeat the following part:
and (not (#Image='myVariableToIgnore'))
The folowing XML is valid for PHP tool PHPMD 2.2.3
<?xml version="1.0"?>
<!DOCTYPE ruleset>
<ruleset
name="My PMD ruleset for symfony 2.5"
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"
>
<rule ref="rulesets/unusedcode.xml" />
<rule ref="rulesets/codesize.xml" />
<rule ref="rulesets/cleancode.xml" />
<rule ref="rulesets/controversial.xml" />
<rule ref="rulesets/design.xml" />
<rule ref="rulesets/naming.xml">
<exclude name="ShortVariable" />
</rule>
<rule ref="rulesets/naming.xml/ShortVariable">
<properties>
<property name="exceptions" value="id,em" />
</properties>
</rule>
</ruleset>
Update xml
<rule ref="category/java/codestyle.xml/ShortVariable">
<properties>
<property name="xpath">
<value>
//VariableDeclaratorId[(string-length(#Image) < 3) and (not (#Name='id'))]
[not(ancestor::ForInit)]
[not((ancestor::FormalParameter) and (ancestor::TryStatement))]
</value>
</property>
</properties>
</rule>
I would like to make checkstyle ignore missing javadoc for #throws clauses in tests, but complain in non-tests.
Because supression files do not support subproperties of the JavadocMethod, I am forced to either ignore javadoc in tests altogether or not at all, with no granularity. This is also the conclusion of this other question.
Here's what I'm trying now: could I have two JavadocMethod modules with different id's (e.g. test and notest) in my checkstyle configuration, and selectively supress the test module on non-tests and viceversa?
I cannot get this to work, and I'm starting to think I can't have a duplicate module in checkstyle. Any insights?
Here are my rules regarding JavadocMethod in the configuration xml:
<module name="JavadocMethod">
<property name="id" value="nontest"/>
</module>
<module name="JavadocMethod">
<property name="id" value="test"/>
<property name="allowMissingThrowsTags" value="true"/>
</module>
And this is my supression file:
<suppressions>
<!-- Supress non-test-doc on tests -->
<suppress id="nontestdoc" files=".*(?:Test|IT).*java" />
<suppress id="testdoc" files=".*(?!Test|IT).*java" />
</suppressions>
Thanks!
You can have duplicate module in checkstyle.
Tried with 2 Indentation module with tab 2 and tab 4 respectively. And used the suppression.xml like following
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress id="IndnA" files=".*\.java"/>
<suppress id="IndnB" files=".*\.java"/>
</suppressions>
and what is the regex .*(?:Test|IT).*java and .*(?!Test|IT).*java for? Why are you using LookAhead?
please check with files as .*\.java whether that is working or not.