Since: PMD 3.7
In J2EE, the getClassLoader() method might not work as expected. Use Thread.currentThread().getContextClassLoader() instead.
//PrimarySuffix[@Image='getClassLoader']
public class Foo {
ClassLoader cl = Bar.class.getClassLoader();
}
Since: PMD 4.0
The EJB Specification states that any MessageDrivenBean or SessionBean should be suffixed by 'Bean'.
//TypeDeclaration/ClassOrInterfaceDeclaration
[
(
(./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'SessionBean')])
or
(./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'MessageDrivenBean')])
)
and
not
(
ends-with(@Image,'Bean')
)
]
public class SomeBean implements SessionBean{} // proper name
public class MissingTheProperSuffix implements SessionBean {} // non-standard name
Since: PMD 4.0
A Remote Home interface type of a Session EJB should be suffixed by 'Home'.
//ClassOrInterfaceDeclaration
[
(
(./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBHome')])
)
and
not
(
ends-with(@Image,'Home')
)
]
public interface MyBeautifulHome extends javax.ejb.EJBHome {} // proper name
public interface MissingProperSuffix extends javax.ejb.EJBHome {} // non-standard name
Since: PMD 4.0
The Local Interface of a Session EJB should be suffixed by 'Local'.
//ClassOrInterfaceDeclaration
[
(
(./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBLocalObject')])
)
and
not
(
ends-with(@Image,'Local')
)
]
public interface MyLocal extends javax.ejb.EJBLocalObject {} // proper name
public interface MissingProperSuffix extends javax.ejb.EJBLocalObject {} // non-standard name
Since: PMD 4.0
The Local Home interface of a Session EJB should be suffixed by 'LocalHome'.
//ClassOrInterfaceDeclaration
[
(
(./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBLocalHome')])
)
and
not
(
ends-with(@Image,'LocalHome')
)
]
public interface MyBeautifulLocalHome extends javax.ejb.EJBLocalHome {}// proper name
public interface MissingProperSuffix extends javax.ejb.EJBLocalHome {} // non-standard name
Since: PMD 4.0
Remote Interface of a Session EJB should not have a suffix.
//ClassOrInterfaceDeclaration
[
(
(./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBObject')])
)
and
(
ends-with(@Image,'Session')
or
ends-with(@Image,'EJB')
or
ends-with(@Image,'Bean')
)
]
/* Poor Session suffix */
public interface BadSuffixSession extends javax.ejb.EJBObject {}
/* Poor EJB suffix */
public interface BadSuffixEJB extends javax.ejb.EJBObject {}
/* Poor Bean suffix */
public interface BadSuffixBean extends javax.ejb.EJBObject {}
Since: PMD 4.1
Web applications should not call System.exit(), since only the web container or the application server should stop the JVM. This rule also checks for the equivalent call Runtime.getRuntime().exit().
//Name[
starts-with(@Image,'System.exit')
or
(starts-with(@Image,'Runtime.getRuntime') and ../../PrimarySuffix[ends-with(@Image,'exit')])
]
public void bar() {
System.exit(0); // never call this when running in an application server!
}
public void foo() {
Runtime.getRuntime().exit(0); // never stop the JVM manually, the container will do this.
}
Since: PMD 4.1
According to the J2EE specification, an EJB should not have any static fields with write access. However, static read-only fields are allowed. This ensures proper behavior especially when instances are distributed by the container on several JREs.
//ClassOrInterfaceDeclaration[
(
(./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'SessionBean')])
or
(./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'EJBHome')])
or
(./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'EJBLocalObject')])
or
(./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'EJBLocalHome')])
or
(./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBObject')])
)
and
(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration[
(./FieldDeclaration[@Static = 'true'])
and
(./FieldDeclaration[@Final = 'false'])
])
]
public class SomeEJB extends EJBObject implements EJBLocalHome {
private static int CountA; // poor, field can be edited
private static final int CountB; // preferred, read-only access
}
Since: PMD 4.1
The J2EE specification explicitly forbids the use of threads.
//ClassOrInterfaceType[@Image = 'Thread' or @Image = 'Runnable']
// This is not allowed
public class UsingThread extends Thread {
}
// Neither this,
public class OtherThread implements Runnable {
// Nor this ...
public void methode() {
Runnable thread = new Thread(); thread.run();
}
}