checkstyle disallow SuppressWarnings annotation unless there is a comment nearby - checkstyle

In our project, we sometimes have to have some warnings suppressed (e.g. "WeakerAccess" might be suppressed as project is also used as a lib in another project, or "expression is always false" for instanceof a checked exception that is thrown from a lib that masks the fact of throwing that exception).
On the other hand, it's not good to just add a suppression, as it might be unclear why is it there. So, I'd like to add a checkstyler rule that would only allow SuppressWarnings annotation if there is a comment nearby. That should be enough for people to start adding explanations.
But I can't find a way to do that. There is this block:
<module name="SuppressWarnings">
<property name="format"
value="^unchecked$|^unused$"/>
<property name="tokens"
value="
CLASS_DEF,INTERFACE_DEF,ENUM_DEF,
ANNOTATION_DEF,ANNOTATION_FIELD_DEF,
ENUM_CONSTANT_DEF,METHOD_DEF,CTOR_DEF
"/>
</module>
and some stuff about special comments to turn off checkstyler for a line, but it is just another suppress warnings thing that would need an explanation as well... But is there a way to say that suppression is OK if there is any comment nearby (on a line before or on the same line)?

I recommend using 2 checks in unison. Use SuppressWarningsCheck to flag the methods you want documented and display an error message that says it is a violation because it is not documented. Then use SuppressWithNearbyCommentFilter to suppress violations of the other check when documentation is added. For the filter to work, the documentation must start with a specific text so it doesn't falsely suppress SuppressWarnings that don't really have a documentation.
Example:
$ cat TestClass.java
public class TestClass {
//SuppressWarnings: this is my reason for the suppression
#SuppressWarnings("unchecked")
void method() {
}
//this is just a comment and not a reason
#SuppressWarnings("unused")
void method2() {
}
#SuppressWarnings("unused")
void noComment() {
}
}
$ cat TestConfig.xml
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="charset" value="UTF-8"/>
<module name="TreeWalker">
<module name="SuppressWarnings">
<property name="format" value="^(unchecked|unused)$"/>
<message key="suppressed.warning.not.allowed"
value="The warning ''{0}'' cannot be suppressed at this location unless a comment is given for the reason for the suppression." />
<property name="tokens" value="CLASS_DEF,INTERFACE_DEF,ENUM_DEF,ANNOTATION_DEF,ANNOTATION_FIELD_DEF,ENUM_CONSTANT_DEF,METHOD_DEF,CTOR_DEF"/>
</module>
<module name="SuppressWithNearbyCommentFilter">
<property name="commentFormat"
value="SuppressWarnings: .{10,}"/>
<property name="checkFormat" value="SuppressWarnings"/>
<property name="influenceFormat" value="3"/>
</module>
</module>
</module>
$ java -jar checkstyle-8.18-all.jar -c TestConfig.xml TestClass.java
Starting audit...
[ERROR] TestClass.java:8:23: The warning 'unused' cannot be suppressed at this location unless a comment is given for the reason for the suppression. [SuppressWarnings]
[ERROR] TestClass.java:12:23: The warning 'unused' cannot be suppressed at this location unless a comment is given for the reason for the suppression. [SuppressWarnings]
Audit done.
Checkstyle ends with 2 errors.
You'll notice there are 2 violations but 3 SuppressWarnings. The first example shows how to correctly suppress that there is no documentation. The 2nd shows just a comment but not a documentation on the suppression, and the 3rd shows no comment at all.
<property name="format" value="^(unchecked|unused)$"/>
This specifies only documentation will be required for unchecked and unused suppressions. If you want documentation for all types but those 2, I recommend the expression "^((?!unchecked|unused).)*$".

Related

checkstyle - prohibit initializing object of type

suppose I have an external library with a class called Foo. I can't change Foo to have a private constructor, but I have a FooFactory class that I wrote.
So I have FooFactory.getAFoo() but I want checkstyle to catch any new Foo() in the rest of my code, to force using the factory.
I have this:
<module name="IllegalTokenText">
<property name="tokens" value="LITERAL_NEW"/>
<property name="format" value="Foo"/>
</module>
but this doesn't seem to detect a new Foo().
I could use a regex but this is much cleaner.
I had a similar problem with preventing extending a class:
<module name="IllegalTokenText">
<property name="tokens" value="EXTENDS_CLAUSE"/>
<property name="format" value="AndroidTestCase"/>
</module>
Neither of these checkstyle module seem to do anything at all.
What am I doing wrong?
IllegalTokenText checks for illegal text on the token itself, not on subsequent IDENT tokens or some such. So that is why it seems to do nothing in your case.
In your case, you may want to try using the SevNTU Checkstyle extension, which offers a check called ForbidInstantiation which might solve your problem. They have no documentation that I am aware of, so I am linking the source code with Javadoc. When you use SevNTU Checkstyle, be sure to use the right versions of regular Checkstyle and SevNTU Checkstyle, because not all combinations are compatible (overview).
If that does not help, you will have to roll your own.

CAS primaryAuthenticationHandler ldapAuthenticationHandler

I think I've exhausted searching and need to ask this seemingly very popular question about CAS configuration for Active Directory. I followed the steps on CAS docs to modify the deployerConfigContext.xml to include the ldapAuthenticationHandler bean.
But seems like CAS is continuing to use AcceptUsersAuthenticationHandler defined in the same file in the primaryAuthenticationHandler tag.
Question: So basically I need to replace AcceptUsersAuthenticationHandler with ldapAuthenticationHandler as the default authenticator. What is the correct syntax to do so in the following snippet?
<bean id="primaryAuthenticationHandler"
class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
<property name="users">
<map>
<entry key="casuser" value="Mellon"/>
</map>
</property>
</bean>
This is what I have tried so far:
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.LdapAuthenticationHandler"></bean>
java.lang.NoSuchMethodException: org.jasig.cas.authentication.LdapAuthenticationHandler.<init>()
<bean id="primaryAuthenticationHandler" class="org.jasig.cas.authentication.ldapAuthenticationHandler"></bean>
java.lang.ClassNotFoundException: org.jasig.cas.authentication.ldapAuthenticationHandler
<bean id="primaryAuthenticationHandler" class="ldapAuthenticationHandler"></bean>
java.lang.ClassNotFoundException: ldapAuthenticationHandler
Did you add the dependency in pom.xml?
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-server-support-ldap</artifactId>
<version>${cas.version}</version>
</dependency>
Indeed, LdapAuthenticationHandler doesn't implement a default constructor, you need to configure a org.ldaptive.auth.Authenticator on the attribute c:authenticator-ref:
<bean id="ldapAuthenticationHandler"
class="org.jasig.cas.authentication.LdapAuthenticationHandler"
p:principalIdAttribute="mail"
c:authenticator-ref="authenticator"/>
LDAP authentication is not as simple as the default hardcoded user/password authentication handler. In this link you can see an example on how to configure a connection to Active Directory: Active Directory Authentication
Following the example, you will find in "LDAP Properties Starter" some properties defined. You will need to copy them to the file cas.properties on the same folder as deployerConfigContext.xml. You have to adjust the properties to your usecase and be aware that some of the properties names don't correspond with the ones on the xml examples.

Issue upgrading from Jackson 1.9 to 2.5 using Spring 3.1.2 - ProviderBase class not found

I'm trying to upgrade a current project from Jackson 1.9 to 2.5. Everything was going well until I tried to startup my WAS 7 server and receive this error:
org.springframework.beans.factory.CannotLoadBeanClassException: Error
loading class
[com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider] for bean
with name 'jaxbProvider' defined in ServletContext resource
[/WEB-INF/spring/applicationContext-configuration.xml]: problem with
class file or dependent class; nested exception is
java.lang.NoClassDefFoundError:
com.fasterxml.jackson.jaxrs.base.ProviderBase
This appears to be in relation to trying to register the Jackson Provider in my web.xml below:
<!-- Jackson Provider -->
<bean id="jaxbProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" >
<property name="mapper" ref="jacksonObjectMapper"/>
</bean>
<bean id="jacksonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" >
<property name="annotationIntrospector" ref="jacksonAnnotationIntrospector"></property>
</bean>
<bean id="jacksonAnnotationIntrospector" class="com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair" >
<constructor-arg ref="primaryAnnotationIntrospector" />
<constructor-arg ref="secondaryAnnotationIntrospector" />
</bean>
<bean id="primaryAnnotationIntrospector" class="com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector" />
<bean id="secondaryAnnotationIntrospector" class="com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector" />
I have the following jars on my classpath:
jackson-annotations-2.5.0.jar
jackson-core-2.5.0.jar
jackson-databind-2.5.0.jar
jackson-jaxrs-json-provider-2.5.0.jar
jackson-module-jaxb-annotations.2.5.0.jar
Now from my understanding its looking for this fellow:
com.fasterxml.jackson.jaxrs.base.ProviderBase
but can't find it. A google search reveals that class as belonging to a
jackson-jaxrs-provider project, but I can't find a specific jar for that. I think that's because that is just a base for the jackson-jaxrs-json-provider.2.5.0.jar that I already included. So shouldn't it inherently be able to see that base class through the jackson-jaxrs-json-provider.2.5.0.jar??
If anyone has an idea of what could be wrong I would be very appreciative!
Thanks.
If you used Maven, adding jackson-jaxrs-json-provider as a dependency, you will see all the following pulled in
(I had an image from another post with v2.2.3- disregard the version)
As you can see, it does depend on a jackson-jaxrs-base, which is where the ProviderBase is located.
You can download it here (just click the 2.5.0, then the Download Bundle)

Checkstyle different rules for different files

I have one file which contains rules for the project.
I want my unit tests methods to be allowed to have underscore in their names.
Like myMethod_should_call_someClass_someMehod. Currently I have one configuration, which is applied to all files in the project.
My question is it possible to somehow configure checkstyle, so, for example I specify specific rules for all files that are ending with *Test.java.
Currently the only solution I found is to provide SuppressionFilter and exclude all files ending with *Test.java. But is there a way I could provide a different MethodNameCheck module with different format for test files?
You must define the MethodName check twice, with one instance checking the regular methods, and the other checking the test methods. Note the id property, which we will use to restrict the checks to their respective domains:
<module name="MethodName">
<property name="id" value="MethodNameRegular"/>
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
</module>
<module name="MethodName">
<property name="id" value="MethodNameTest"/>
<property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
</module>
Next, the regular check must be suppressed for test methods and vice versa. This works only if you have a criterion by which to distinguish between the two kinds of classes. I use the Maven directory convention, which puts regular classes under src/main and test classes under src/test. Here is the suppression filter file:
<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files="[\\/]src[\\/]test[\\/].*" id="MethodNameRegular" />
<suppress files="[\\/]src[\\/]main[\\/].*" id="MethodNameTest" />
</suppressions>
Building on barfuin's answer, I preferred not to have (yet) another XML file floating around. However, it is possible to configure suppressions directly in the CheckStyle XML config file:
<module name="SuppressionSingleFilter">
<metadata name="net.sf.eclipsecs.core.comment" value="Suppress MethodNameRegular check on unit tests"/>
<property name="files" value=".*[\\/]src[\\/]test[\\/]"/>
<property name="id" value="MethodNameRegular"/>
</module>
<module name="SuppressionSingleFilter">
<metadata name="net.sf.eclipsecs.core.comment" value="Suppress MethodNameTest check except on unit tests"/>
<property name="files" value=".*[\\/]src[\\/](?!test[\\/])"/>
<property name="id" value="MethodNameTest"/>
</module>
(This would be in addition to the two MethodName checks.)

How do I alter checkstyle configuration file when using sonar?

I'm trying to suppress specific checkstyle warnings in my code. The default way seems to be to wrap code in comments eg: // CHECKSTYLE:OFF ... // CHECKSTYLE:ON. At the very least I'd like to give a reason for which I found the follow post. I don't know where the configuration file would be when using sonar, can anyone help?
How can you suppress checkstyle checks within a block of code only for specific rules?
Recommend reading the documentation on SuppressionCommentFilter (it is buried at bit) for lots of examples.
An example of how to do configure the filter is:
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CSOFF: ([w|]+)"/>
<property name="onCommentFormat" value="CSON: ([w|]+)"/>
<property name="checkFormat" value="$1"/>
</module>
You can then use the following to turn off the RequireThis check for a block of code:
// CSOFF: RequireThis
... code
// CSON: RequireThis
Login to Sonar as admin, then go to "Settings" (link at top-right, next to your username), select the "Java" category, then the "CheckStyle" tab.
After that, enter the <module> section from your post above into the "Filters" textarea.