Is it possible to use Checkstyle to forbid usage of some constructors or method that use system-dependent defaults (locale, charset, etc..). I prefer to enforce a policy where the programmer should be explicit about system-dependent values. So I consider the following items to be dangerous:
- all the constructors of
java.io.FielWriter
- using system-dependent encoding
- the
OutputStreamWriter(OutputStream os)
constructor ofjava.io.OutputStreamWriter
- using system-dependent encoding
- the
java.lang.String.toLowerCase()
method- using system default locale
- The
java.util.Calendar.getInstance()
method- using system default locale and default timezone
(the list goes on, you get the picture).
Is it possible to enforce this using Checkstyle 5.5?
You can't do this by default. However, you can implement your own checker which checks for these methods.
The first option is to use Miscellaneous->Regexp. This is obviously only possible if you can find violations with a regexp. You will need to set illegalPattern = true. This would be a good place to start, I think.
The second options is to create your own check. See Writing Checks.
There are limitations to writing checkers. The first and most important is that you can't see other files. There isn't any cross checking. From the site:
So you couldn't check for instance that the java is calling one method which has an alternative with a Locale. You could use a blacklist of methods which you're not allowed to call. So for instance calls to new FileWriter() would check the number of parameters passed, or such like.
As Matthew and emory stated, there isn't a perfect solution with check style. Here's my suggestion:
FileWriter\(
" and a subclassSystemIndependentFileWriter
with only some of the super class' constructors.toLowerCase()
" and hope, that nobody did create a method with the same name. Or use FindBugs to catch this one.Calendar.getInstance()
". I don't see a problem with that one.Hopefully it will throw only a few false positives, which could be put on the ignore list. Eventually you need to tweak it to catch line breaks or other misplaced whitespaces.
I think an Annotation Processor would be more suitable to this task. From Matthew Farwell's answer "You cannot determine the type of an expression."
Assume you use a third party jar which contains class FancyWriter which extends FileWriter. You illegally put a
x = new FancyWriter ( ) ;
in your code. CheckStyle will not find it because it is using regular expressions and it is not smart enough to know that FancyWriter is a FileWriter. I think you could write an annotation processor that figures out FancyWriter is really a FileWriter and is illegal.OTH, someone - in theory - could write an extension of an illegal class that irons out the system dependency. For example, assume that FileWriter had a method in which it gets the system encoding. If LegalWriter extends FileWriter and override the method then we should not reject LegalWriter just b/c it extended an illegal class.
If you are using third party jars, how would their classes are legal. Just because they don't extend an illegal class, doesn't mean they don't use it. Then if you use one of their classes, your code is system dependent.