I have two situations I need a checkstyle check for. Let's say I have a bunch of objects with the annotation #BusinessLogic. I want to do a first pass through all *.java files creating a Set with the full classnames of these objects. Let's say ONE of the classes here is MyBusinessLogic. NEXT, and as part of a custom checkstyle checker, I want to go through and fail the build if there is any lines of code that say "new MyBusinessLogic()" in any of the code. We want to force DI when objects are annotated with #BusinessLogic. Is this possible with checkstyle? I am not sure checkstyle does a dual pass.
Another option I am considering is some gradle plugin perhaps that scans all java files and writes to a file the list of classes annotated with #BusinessLogic and then running checkstyle after that where my checker reads in the file?
My next situation is I have a library delivered as a jar so in that jar, I also have classes annotated with #BusinessLogic and I need to make sure those are also added to my list of classes that should not be newed up manually and only created with dependency injection.
Follow up question from the previous question here after reading through checkstyle docs:
How to enforce this pattern via gradle plugins?
thanks,
Dean
Is it possible to write a dual pass checkstyle check?
Possible, yes, but not officially supported. Support would come at https://github.com/checkstyle/checkstyle/issues/3540 but it hasn't been agreed on.
Multi-file validation is possible with FileSets (still not officially supported), but it becomes harder with TreeWalker checks. This is because TreeWalker doesn't chain finishProcessing to the checks. You can implement your own TreeWalker that will chain this finishProcessing to implementation of AbstractChecks.
You will have to do everything in 1 pass with this method. Log all new XXX and classes with annotation #YYY. In the finishProcessing method, correlate the information obtained between the 2 and print a violation when you have a match.
I have a library delivered as a jar
Checkstyle does not support reading JARs or bytecode. You can always create a hard coded list as an alternative. The only other way is build your own reader into Checkstyle.
Related
I have a question to ask regarding checkstyle.
It seems that the checkstyle api accepts both module name,
ConstantName and ConstantNameCheck (ConstantName with Check concatenated) for the configuration file, checkstyle.xml.
I would like to ask why is there a double standard here even though documentations on http://checkstyle.sourceforge.net/ only promotes ConstantName module and what is the difference between using either of them? Will either one of them gets deprecated in future?
Thanks!
Behind the scenes, the ConstantName check is implemented by a Java class called
com.puppycrawl.tools.checkstyle.checks.naming.ConstantNameCheck.
You could actually refer to the module in checkstyle.xml by this so-called "fully qualified" name. The other notations are shorthand offered by Checkstyle for convenience. ConstantNameCheck is the simple name of the implementing Java class, and ConstantName is still shorter. Checkstyle will try all three variants when looking for the module in your checkstyle.xml. So, there is no difference between these notations.
The recommended way is to use the most concise form, ConstantName, but as far as I know, none of the other forms is going to get deprecated any time soon.
How to check The value of the local variable is not used and The value of the field is not used using Checkstyle? In Eclipse there is a warning about that. But there's no in Checkstyle (i use sun_checks.xml, slightly modified).
I tried to write my own check, but being a newbie, only found how to calculate variable declarations (using TokenTypes.VARIABLE_DEF), but i am not sure how to find namely usage of these variables and fields...
Checkstyle can't do that, I'm afraid, but PMD (rule) and FindBugs (rule) can.
Checkstyle and PMD operate only on the Java source, and it is harder to deduce field and variable use only from the source. FindBugs operates on the compiled class files, so it has an easier job in this case. PMD can only detect unused private fields and variables, which can be found by looking at a single source file.
Writing an "unused private field/variable detector" for Checkstyle is possible, if tedious. I would recommend going with the PMD tool for this, which also features a light-weight Eclipse plugin.
Checkstyle 9.3 introduced the UnusedLocalVariable check which reports unused local variables. It does not detect unused fields.
To enable this check:
<module name="UnusedLocalVariable"/>
As of Checkstyle 10.1, this check still has some limitations: it doesn't report unused method arguments nor unused pattern variables. But at least it covers the most common cases with local variables.
References:
Checkstyle 9.3 Release Notes
UnusedLocalVariable module documentation
Github issue
Is there a way to use the maven-processor-plugin (or any other plug-in) to execute annotation processors listing the ones to skip? I have little control on the processors my dependencies might use but I do know the one I want skipped.
The only option in the usage page is to list the ones you want to include but not the other way around.
Is there a way to do this in Maven?
This is not a question of the maven plugin, but of the availability of javac options. According to the javac reference on annotation processing
Processors are located by means of service provider-configuration files named META-INF/services/javax.annotation.processing.Processor on the search path. Such files should contain the names of any annotation processors to be used, listed one per line. Alternatively, processors can be specified explicitly, using the -processor option.
So for now there's no way to remove an annotation processor, just whitelist the ones you want to run.
We work with a lot of legacy code and we think about introducing some metrics for new code. Is it possible to let Findbugs and Checkstyle run on changed files only instead of a complete project?
It would be nice to assure that only file with a minimum of quality is checked in, but the code base itself is not (yet) touched and evaluated not to confuse people by thousands of issues.
In theory, it would be possible. You would use a shell script to parse the SVN (or whatever SCM) change logs after a given start date, identify the .java files from these change sets and build two patterns from these:
The Findbugs Maven Plugin expects a comma-separated list of class (or
package) names for the parameter onlyAnalyze, so you'll have
to translate file names to fully qualified class names (this will get
tricky when you're dealing with inner classes)
The Maven Checkstyle Plugin is even worse, it expects a
configuration file for its packageNamesLocation parameter.
Unfortunately, only packages are allowed, not individual files. So
you'll have to translate file names to packages.
In the above examples I assume that you are using maven. I am pretty sure that similar things can be done with ant, but I wouldn't know.
I myself would probably use a Groovy script instead of a shell script to achieve the above results.
Findbugs has ant tasks that can do diffs against different findbugs results to see just the deltas, so only reporting new bugs, see
http://findbugs.sourceforge.net/manual/datamining.html
I'm having trouble finding good advice and common practices for the use of namespaces in Clojure. I realize that namespaces are not the same as Java packages so I'm trying to tease out the conventions in Clojure, which seem surprisingly hard to determine.
I think I have a pretty good idea how to split functions into clj files and even roughly how I'd want to organize those files into directories. But beyond that I'm having trouble finding the mechanics for my dev environment. Some inter-related questions:
Do I use the same uniqueness conventions for Clojure namespaces as I would normally use for Java packages? [ie backwards-company-domain.project.subsystem]
Should I save my files in a directory structure that matches my namespaces? [ala Java]
If I have multiple namespaces, do I need to compile all of my code into a jar and add it to my classpath to make it accessible?
Should each namespace compile to one jar? Or should I create a single jar that contains clj code from many namespaces?
Thanks...
I guess it's ok if you think it helps, but many Clojure projects don't do so -- cf. Compojure (using a top-level compojure ns and various compojure.* ns's for specific functionality), Ring, Leiningen... Clojure itself uses clojure.* (and clojure.contrib.* for contrib libraries), but that's a special case, I suppose.
Yes! You absolutely must do so, or else Clojure won't be able to find your namespaces. Also note that you musn't use the underscore in namespace names or the hyphen in filenames and wherever you use a hyphen in a namespace name, you must use an underscore in the filename (so that the ns my.cool-project is defined in a file called cool_project.clj in a directory called my).
You need to make sure all your stuff is on the classpath, but it doesn't matter if it's in a jar, multiple jars, a mixture of jars and directories on the filesystem... As long as it obeys the correct naming conventions (your point no. 2) you should be fine.
However, do not compile things ahead-of-time if there's no particular reason to do so -- this may prevent your code from being portable across various versions of Clojure without providing any benefits besides a slightly improved loading time.
You'll still need to use AOT compilation sometimes, notably in some Java interop scenarios -- the documentation of the relevant functions / macros always mentions that. There are examples of things requiring AOT in clojure.contrib; I've never needed it, so I can't provide much in the way of details.
I'd say you should use jars for functional units of code. E.g. Compojure and Ring get packaged as single jars containing many namespaces which together compose the whole package. Also, clojure.contrib is notably packaged as a single jar with multiple unrelated libraries; but that again may be a special case.
On the other hand, a single jar containing all of your project's code together with its dependencies might occasionally be useful for deployment. Check out the Leiningen build tool and its 'uberjar' facility if you think that sort of thing may be useful to you.
Strictly speaking, not necessary, though many Java projects have dropped that convention as well, especially for internal projects or private APIs. Do avoid single-segment namespaces though, which would result in classfiles being generated in the default package.
Yes.
Regarding 3 & 4, packaging and AOT compilation are entirely orthogonal to the question of namespace conventions.