Does Checkstyle require compiled classes? - java

Can anyone confirm that Checkstyle is meant to be run with the compiled versions of classes on the classpath?
We currently run it on the Java files alone but recently we've been encountering some errors around the "RedundantThrows" and "JavadocMethod" checks. The error is "Unable to find class information for X". Searching online we've found that the solution is to add the compiled classes to the classpath before running Checkstyle.
Our problem is that our Checkstyle audit currently runs on a server that only has access to the source and we just want to confirm that Checkstyle will in fact need access to compiled classes. Can't seem to find "definitive proof" on the official site.

Checkstyle is perfectly happy with the source files only. Compiled versions of your classes are not required.
However, it is still better to have compiled classes available, because a few individual checks do make use of compiled .class files. These checks mention the fact that they need binaries in their documentation. One is the JavadocMethod check you mention. This one will still function without binaries, but you may see some irritation in the logs.
The other check I can think of needing compiled classes is RedundantThrows. This one will probably not do much good with only sources. You'd have to give it a try.
In both cases, you can suppress the load errors by setting the suppressLoadErrors property to true. Without binaries, the check will not be able to gather inheritance information. So some features of the check will be limited, but it will otherwise work fine or at least not bother you.

Related

How Auto Complete in java works with Reflection?

I have heard that Eclipse uses reflection to provide its auto complete features.But How does it work actually?I searched Google but found no good article on it.Can Anyone please explain the procedures or provide me with any useful article on it.Thanks in advance.
The reflection APIs can only tell you about code that is running (or at least, it is loaded within a program, in a complete compiled state, ready to run). When you're editing your code, it's not running, and it's not loaded into a JVM, so it can't possibly be examined using reflection. There is also information in Eclipse's auto-complete that is never available via reflection, such as names of local (within-method) variables.
Instead, Eclipse has its own compiler. It reads the source code directly and uses this to build its own understanding of the available classes, methods, constructors, fields and local variables. That information is used by several editing features including auto-complete.
Additionally, when the source code is not available, Eclipse can get partial information for auto-complete by reading compiled .class files directly. The .class file structure is fully documented. (There are several reasons why this is only "partial" information. For one thing, it does not include information about local variables if the class was compiled without debugging information. It also does not typically include the names of method parameters. (Java 8 has added a new "MethodParameters" attribute in the class file format which can be used to record the method parameter names, but javac does not do this by default.))
I'm no expert on Eclipse's internals but I think/hope this is accurate.

Replacing java class?

I'm working on a sandbox feature for my java antivirus, and I've come into a question: Does the specified package on a class matter for compilation?
Example:
I'm running a program that wants to use Runtime.getRuntime().exec(), when the classloader attempts to load that to run a method, does it check the package qualified in the file, if they exist? I would prefer not to try and change files in the JVM, but to simply load ones from a different package. I can accomplish the loading and such, but my only dilemma, will it crash and burn? Inside the java, it would be registered as say, java.lang.Runtime, but the compiled code will say for example pkg.pkg.Runtime and will it need to extend the old runtime? My guess is that extending the old runtime would just break it. Does anyone know anything about this? I'm working on making a testable example, but I'm still a bit away and wanted to get some answers, as well as this might benefit some people.
Does the specified package on a class matter for compilation?
Yes it does matter. A class called pkg.pkg.Runtime() cannot be loaded as if it was java.lang.Runtime.
Furthermore, if my memory is correct, the JVM has some additional security measures in it to prevent normal applications from injecting classes into core packages such as java.lang.
If you need to change the behaviour of the java.lang.Runtime class (for experimental purposes!) then I think you will need to put your modified version on the boot classpath, ahead of the "rt.jar" file.
However:
This level of tinkering can easily result in JVM instability; i.e. hard JVM crashes that are difficult to diagnose.
If your aim is to produce a "production quality" tool, then you will find that things that involve tinkering with the JVM are not considered acceptable. People are going to be very suspicious of installation instructions that say things like "add this to your installed JVM's bootclasspath".
Distributing a "tinkered with" JVM may fall foul of Oracle's Java licensing agreement.
My advice would be to look for a less intrusive way of doing what you are trying to do. For instance, if you are trying to do virus checking, either do it outside of the JVM, or in a custom application classloader.
You commented:
I have a custom classloader, my question is: If I compile a class that is labelled as say, pkg.pkg.Runtime, can I register in my classloader as java.lang.Runtime?
As I said above, no you can't. A bytecode file has the classname embedded in it. If you attempt to "pull a swifty" by loading a class with a different name, the JVM will throw an Error.
And:
If not, then how can I replace the class? If the compiled package name has to equal the request referenced naming, then can I modify the .class file to to match, or perhaps compile it as if it were in the java.lang package?
That's what you would have to do. You need to name the class java.lang.Runtime in the source code and compile it as such.
But what I meant by my advice above is that you should use do the virus checking in the class loader. Forget about trying to replace / modify the behaviour of Runtime. It is a bad idea for the reasons I listed above.

Find unused code in Java webapp

I have a Tomcat-powered webapp that builds to a war and is deployed. It's been used for a few somewhat different tasks over the years, and it has lots and lots and lots of classes and libraries.
I'd like to do some sort of automated census of used and unused classes (and maybe even dependencies) and get a report back for which classes, methods, or even lines that have not been executed over a few days of production use.
Is there a tool that could generate such a report for me?
You're looking for a code coverage tool.
For Java, try EMMA:
http://emma.sourceforge.net/
If you are talking about statistics of unused code (functionally) in production system you can start with simply enabling the "-verbose:class" as startup parameter. I don't think Sun JDK (at least JDK 5)supports regular expression to restrict the log to specific package(s).
It's better to analyze the unused method/block using static analysis tools like PMD/Sonar rather than instrumenting to method/line level.

Weblogic application complains about some classes missing, how to debug?

I have a rather complex J2EE app I don't have any documentation for and I am trying to get it to run.
I have gotten the ant build script to compile a EAR file that contains a WAR file, but this application even though I get "successfully deployed" on weblogic console is still not working.
There are many required jars missing from the EAR file, hence I get errors about missing classes on the console log when I deploy the app. Sometimes even after I check a particular class is there I still get the error.
What is a best way to debug and get this application running?
Is there any shortcuts in J2EE/Java to "find all dependencies", apps anybody knows to analyze code and find dependencies or anything like that?
Is there any shortcuts in J2EE/Java to "find all dependencies", apps anybody knows to analyze code and find dependencies or anything like that?
Do you mean a compiler? I'm actually semi serious here (even if the compiler won't give you the name of a missing JAR). Indeed, if you are compiling that application successfully with Ant, then you likely have all dependencies required at compile time (you may need more of them at runtime but, well, you'll need to execute the code to identify them). Maybe you just need to add more of them in the EAR during the packaging. Or maybe you need to add more dependencies at the app server classpath level.
In both case, search engines like jarFinder.com or Docjar.com or Jarhoo.com might help you to identify missing JARs and to solve your ClassNotFoundException or NoClassDefFoundError.
You should actually give readers more details about the missing classes, I'm sure people will be able to give you some hints and point you in the right direction.
I know of no easy way to deal with this. If the application provides an ant task build the EAR then the result should be a self-contained deployable application EAR. It is possible that the EAR requires extra libraries to be added to some class path, without documentation it's really hard to know what.
This phrase is, I guess, at the heart of the problem: "Sometimes even after I check a particular class is there I still get the error." Exactly what do you mean?
You are getting a class not found error but you can see the class in the EAR file? If that's the case then things are really difficult, and may well be some kind of classloader issue. I don't know WebLogic at all, but in WebSphere when deploying an application you have a choice of whether to give precedence to JARs in the EAR or to the same JAR in WebSphere itself. Some Applications demand one or the other setting. If there's anything like that in WebLogic then this may be your problem.
Another possible problem is that the app may depend on infrastructure libraries (Eg. XML parsers) that are supplied by WebLogic, but expects a different version that is supplied with the WebLogic version you are using.
Without documentation that the app is supported on the version of WebLogic you are using, I fear you're fighting a long, hard (or even a losing) battle.
I'd assume you managed to get this application put together and compiled in an IDE, maybe Eclipse. Why not simply put all the Jars that you had available at build time, into the EAR?
If you're having to debug this by trial and error, you can look at the list of missing classes and figure out which jars they belong to by Googling for the class names, or maybe you can find them in your IDE too.
If you have a lot of trouble identifying some classes, post the class names (or the error messages) here and someone should be able to tell you where to find the Jar it belongs in.
If you are able to successfully build and deploy the app, but still getting the errors about missing classes, probably some of the jar classes are called through reflection. You may want to search for reflection API calls in the Project through your IDE.
These calls may be something like,
"Class cls = Class.forName(..); cls.newInstance()."
Sometimes even after I check a
particular class is there I still get
the error.
This may be a deployment issue. check the classpath. Some of the jars may be missing from the Classpath.
Is there any shortcuts in J2EE/Java to
"find all dependencies", apps anybody
knows to analyze code and find
dependencies or anything like that?
I'd start by having another go at getting documentation ... or help ... from the original developers, if you can find them. [IMO, people who develop / provide software without any documentation deserve to be bugged incessantly by people asking silly questions.] But I guess you've already tried that.
Then there are the jarfinder.com and other services as mentioned in another answer. (New to me!)
If that fails, I'd try doing a Google search on the FQNs. The chances are that if the missing classes are part of a commonly used library you will hit the Javadocs ... or a posting from someone else with a similar problem to yours.
If the "Google it" approach fails, use the clues in the package naming for the missing classes to try and find where they come from. If they follow the Sun recommendations, the names should map to a company or (real or pseudo-) organization that you can locate by a web search.

How do I strip the fluff out of a third party library?

It may not be best practice but are there ways of removing unsused classes from a third party's jar files. Something that looks at the way in which my classes are using the library and does some kind of coverage analysis, then spits out another jar with all of the untouched classes removed.
Obviously there are issues with this. Specifically, the usage scenario I put it though may not use all classes all the time.
But neglecting these problems, can it be done in principle?
There is a way.
The JarJar project does this AFAIR. The first goal of the JarJar project is to allow one to embed third party libraries in your own jar, changing the package structure if necessary. Doing so it can strip out the classes that are not needed.
Check it out at http://code.google.com/p/jarjar/.
Here is a link about shrinking jars: http://sixlegs.com/blog/java/jarjar-keep.html
There is a tool in Ant called a classfileset. You specify the list of root classes that you know you need, and then the classfileset recursively analyzes their code to find all dependencies.
Alternatively, you could develop a good test suite that exercises all of the functions that you need, then run your tests under a test coverage tool. The tool will tell you which classes (and statement in them) were actually utilized. This could give you an even smaller set of code than what you'd find with static analysis.
I use ProGuard for this. As well as being an excellent obfuscator, it has a code shrinking phase which can combine multiple JARs and then strip out any unused classes or class members. It does an excellent job at shrinking.
At a previous job, I used a Java obfuscator that as well as obfuscating the code, also removed classes and methods that weren't being used. If you were doing "Class.byName" or any other type of reflection stuff, you needed to tell the obfuscator because it couldn't tell by inspecting the code what classes or methods called by reflection.
The problem, of course, is that you don't know if other parts of the third party library are doing any reflection, and so removing an "unused" class might cause things to break in an obscure case that you haven't tested.
jar is just a zip file, so I guess you can. If you could get to the source, it's cleaner. Maybe try disassembling the class?
Adding to this question, can that improve performance? Since the classes not used would not be JIT compiled improving startup time or does the java automatically detect that while compiling to bytecode and do not even deal with the code that is not used?
This would be an interesting project (has anyone done it already?)
I presume you'd give the tool your jar(s) as a starting point, and the library jar to clean up. It could use reflection to determine which classes your jar(s) reference directly, and which are used indirectly down the call tree (this is not trivial at all, but doable). If it encounters any reflection code in any of the two places, it should give a very loud warning.

Categories

Resources