Showing posts with label bytecode analysis. Show all posts
Showing posts with label bytecode analysis. Show all posts

Tuesday, September 16, 2014

deadcode4j v2.0.0 released

deadcode4j v2.0.0 is out! It is available via Maven central, so it is conveniently available for your Maven project.

What's new?

Although version 2.0.0 adds only a few frameworks to its feature list, e.g. Jetty XML configuration and Spring Data custom repositories, changes "under the hood" were massive and allowed to eliminate two of the most common reasons for false positives: type erasure and constants inlining. Additionally, the custom analyzers are now much more powerful: they now recognize transitive implementation of an interface or a superclass. To keep configuration slick, unnecessary configuration (like ignoring classes that don't even exist) is recognized by deadcode4j and is requested to be removed from the configuration.
All changes are listed in the change log.

Major Release: Usage Statistics

The major release is due to two changes: the deprecated goal find-without-packaging was removed; but most importantly, deadcode4j now requests your permission to send some usage statistics. Those usage statistics will help me understand usage scenarios, project sizes, configuration usage etc. - allowing to improve deadcode4j furthermore. Sending statistics is completely transparent; it is optional and can be skipped permanently or on a per-usage basis.
Do you have an opinion on usage statistics? Do you find it invasive, or do you appreciate my intentions to improve by gathering feedback?

How to use

It's so simple: go to the console, navigate to your Maven project, type
  mvn de.is24.mavenplugins:deadcode4j-maven-plugin:find ‑Dmaven.test.skip=true
and see what it finds.

Hop on over to GitHub to learn more, browse the code, or contribute.

Looking for reference projects & users

Currently I'm using the big legacy application of my employer as a reference project. But I'm slowly running out of false positives, so my feature list is shrinking. That's why I'd love to analyze some more projects to get more feedback. So, if you know of an (open source) candidate I can analyze or if you are using deadcode4j for yourself and want something added or you have some nice ideas, please comment!

Here you can read how it all started.

Friday, June 13, 2014

dead code in Jetty

During today's coding session of our Scout IT Day (ImmobilienScout24's flavor of the FedEx or ShipIt Day), I spent some time analyzing the Jetty project.
It's been a bit cumbersome, as Jetty provides a bunch of classes whose usage is configurable (e.g. the RewriteHandler), so I ended up manually analyzing (i.e. figuring out what the class does) many classes. In the end, only a few classes of the org.eclipse.jetty.util package seem to be dead - if one could say so about classes from a near-public library.

Setup

To analyze Jetty, I used a yet unreleased version, but the current 1.5 release only produces 4 more false positives. Here's the plugin configuration I used:

<plugin>
  <groupId>de.is24.mavenplugins</groupId>
  <artifactId>deadcode4j-maven-plugin</artifactId>
  <version>1.5</version>
  <configuration>
    <modulesToSkip>
      <modulesToSkip>jetty-runner</modulesToSkip>
      <modulesToSkip>examples</modulesToSkip>
      <modulesToSkip>tests/test-webapps</modulesToSkip>
    </modulesToSkip>
  </configuration>
</plugin
I excluded jetty-runner because it unpacks all of Jetty's dependencies and thus classes from e.g. the JSP-API are analyzed and partly recognized as dead. Not what we want to know.
The other two modules define tests and other classes that are not recognized by deadcode4j (and intentionally so).

Results

I ended up with ~150 presumably dead classes out of ~2.000 - but as mentioned before, most of them are simply optional classes that some users probably use. Only candidates that I struggle with are:

  • org.eclipse.jetty.start.Version: Parses a version string. Seems to me like an old "internal" class that is no longer used, hard to imagine that anyone outside of Jetty itself makes use of it.
  • org.eclipse.jetty.util.HostMap: Maps hosts & domains to anything, provides a method to retrieve all entries for a host or it's parent domains. While this has its merits, the fact that it defines its own method to distinguish it from a regular HashMap, one would assume some Jetty code would use it (like e.g. the org.eclipse.jetty.util.IPAddressMap).
  • org.eclipse.jetty.util.TreeTrie: Kind of Map, but with fuzzy getters. This seems so specific (and other flavors like e.g. ArrayTernaryTrie being used internally), it's hard to imagine usages outside of Jetty.
To remove this classes may be too rash (after all, those are public classes in a publicly accessible library), but it seems like they could easily be deprecated for now.
Good job, Jetty maintainers!

About deadcode4j

deadcode4j is a Maven plugin which finds dead code. To use it, go to the console, navigate to your Maven project, type
  mvn de.is24.mavenplugins:deadcode4j-maven-plugin:find ‑Dmaven.test.skip=true
and see what it finds.

Hop on over to GitHub to learn more, browse the code, or contribute.

Here you can read how it all started.

Friday, April 11, 2014

deadcode4j v1.5 released

deadcode4j v1.5 is out! It is available via Maven central, so it is conveniently available for your Maven project.

What's new?

Version 1.5 comes with a ton of new features, nearly doubling the analysis capabilities of deadcode4j: aspects (AOP); Axis & CXF endpoints; a lot of classes being specified in faces-config.xml files, Spring Web Flow XML files, and Apache Tiles XML definition files; Spring XML Namespace Handlers; Hibernate's GenericGenerator annotation is considered even more thoroughly; implementations of ServletContainerInitializer and Spring's flavor, WebApplicationInitializer - just to name the most spectacular. The full list can be found in the change log.

Given that list, if your project uses no other technologies than Spring, Hibernate, Axis, CXF, JAXB, Castor, JEE, JSF, Apache Tiles, Spring MVC or Spring Web Flow, deadcode4j won't report many false positives. With the customization possibilities deadcode4j provides (subclasses, implementations of an interface, annotations and XML parsing), you will be enabled to easily clean up your code base and get rid of classes that just aren't needed anymore.

How to use

It's so simple: go to the console, navigate to your Maven project, type
  mvn de.is24.mavenplugins:deadcode4j-maven-plugin:find ‑Dmaven.test.skip=true
and see what it finds.

Hop on over to GitHub to learn more, browse the code, or contribute.

Looking for reference projects & users

Currently I'm using the big legacy application of my employer as a reference project. But I'm slowly running out of false positives, so my feature list is shrinking. That's why I'd love to analyze some more projects to get more feedback. So, if you know of an (open source) candidate I can analyze or if you are using deadcode4j for yourself and want something added or you have some nice ideas, please comment!

Here you can read how it all started.

Wednesday, November 13, 2013

deadcode4j v1.4 released

deadcode4j v1.4 is out! It is available via Maven central, so it is conveniently available for your Maven project.

What's new?

Version 1.4 was all about customization, so that you can unleash the power of deadcode4j without waiting for the nth feature to be added:

  • Additionally to the annotations that can be configured, you can now define interfaces which, if implemented by a class, mark that code as being in use
  • With annotations and interfaces, there's only one thing missing: superclasses - and they can be configured as well, thus marking subclasses as being in use
  • As deadcode4j processes the whole reactor, there may be some example/testing modules which should not be considered - so now you can specify if a module shouldn't be part of the analysis

This should help you eliminate a good portion of the false positives being found by deadcode4j right now, helping you set up a configuration which recognizes dead code.
Nevertheless, v1.4 brings some more analysis features:

  • Classes being listed in web.xml files as contextClass or contextInitializerClasses parameter for Spring's ContextLoader or FrameworkServlet are recognized as live code
  • Hibernate Annotations processing:
    • Classes referenced by the strategy parameter of a @GenericGenerator annotation are recognized as live code
    • Classes referenced by the type parameter of a @Type annotation are recognized as live code
    • Classes annotated with @TypeDef being referenced by a @Type annotation are recognized as live code
  • package-info classes annotated with JAXB's @XmlSchema annotation are recognized as live code
  • Classes being annotated with any of a bunch of JSF annotations are recognized as live code
  • *Descriptor classes being generated by Castor are recognized as live code

How to use

It's so simple: go to the console, navigate to your Maven project, type
  mvn de.is24.mavenplugins:deadcode4j-maven-plugin:find ‑Dmaven.test.skip=true
and see what it finds.

Hop on over to GitHub to learn more, browse the code, or contribute.

Looking for reference projects & users

Currently I'm using the big legacy application of my employer as a reference project. But I'm slowly running out of false positives, so my feature list is shrinking. That's why I'd love to analyze some more projects to get more feedback. So, if you know of an (open source) candidate I can analyze or if you are using deadcode4j for yourself and want something added or you have some nice ideas, please comment!

Here you can read how it all started.

Monday, October 28, 2013

deadcode4j v1.3 released

I recently released deadcode4j v1.3. It is available via Maven central, so it is conveniently available for your Maven project.

What's new?

Two now analysis modes were added:

  • Classes annotated with Spring annotations like @Component or @Repository (amongst others) are considered to be live code
  • Classes annotated with JEE annotations like @ManagedBean, @Named or @StaticMetamodel are considered to be live code

Additionally, you can specify which annotations mark classes as live code, and configure a custom XML analysis such that an XML element's text content or an attribute is considered to be a class in use. This should help enormously to reduce the number of false positives being recognized.

How to use

It's so simple: go to the console, navigate to your Maven project, type
  mvn de.is24.mavenplugins:deadcode4j-maven-plugin:find -Dmaven.test.skip=true
and see what it finds.

Hop on over to GitHub to learn more, browse the code, or contribute.

Looking for reference projects & users

Currently I'm using the big legacy application of my employer as a reference project. This is ok, as there are still some false positives, providing me with a feature list for a couple of more releases. However, I'd love to analyze some more projects to get even more feedback. So, if you know of an (open source) candidate I can analyze or if you are using deadcode4j for yourself and want something added or you have some nice ideas, please comment!

Sunday, October 13, 2013

deadcode4j v1.2.0 released

Today, I released deadcode4j v1.2.0! It is available via Maven central, so it is conveniently available for your Maven project.

What's new?

Two now analysis modes were added:
  • web.xml files are parsed and each listed servlet, filter & listener is considered to be live code
  • *.tld files are parsed - thus tags, tag extra info classes, listeners, tag library validators & EL functions are considered to be live code

On top of that, if a project uses war packaging the webapp directory is analyzed instead of the project's output directory to catch those web.xml and .tld files. Therefore, the package phase is executed on the fly.
Finally, the plugin now recognizes reactor projects, meaning each listed module will be analyzed by deadcode4j, providing a holistic view over a complex project.

How to use

It's so simple: go to the console, navigate to your Maven project, type
  mvn de.is24.mavenplugins:deadcode4j-maven-plugin:find -Dmaven.test.skip=true
and see what it finds.

Hop on over to GitHub to learn more, browse the code, or contribute.

Looking for reference projects & users

Currently I'm using the big legacy application of my employer as a reference project. This is fine, as I still have a sizable amount of false positives, providing me with a feature list for a couple of more releases. However, I'd love to analyze some more projects to get even more feedback. So, if you know of an (open source) candidate I can analyze or if you are using deadcode4j for yourself and want something added or you have some nice ideas, please comment!

Wednesday, October 9, 2013

Introducing deadcode4j

Motivation

Dead code is everywhere. I guess that most sizable software that underwent at least one major rewrite or is taken care of by agile teams which do minor rewrites every week or so, caries with it at least one dead class; not to mention the one or other dead method. When dealing with legacy code especially - consisting of many modules, older than the programmer with most seniority, with little to no tests - the share of the code base being dead can easily grow up to a double-digit percentage. So, when dealing with such code, you may end up adapting classes when you needn't bother, which you shouldn't try to understand - but just delete them and grin.
And in times of continuous integration, this causes unnecessary energy consumption and time spent in build queues that could be empty, waiting for other stuff to do than compiling and testing code that served its purpose a long time ago.

So, code analysis is a great thing. If your home is the Java world, you should know (and sometimes even make use of) such great analysis tools like FindBugs, PMD, or Checkstyle - to name the probably most prominent. This should at least help you get rid of some dead variables and methods. But those tools are usually only capable of validating local usage, restraining them to find unused private methods. And if you're dealing with code from a time where using the private modifier wasn't en vogue - poor you. And talk about whole classes? Just forget about it.
I don't know of any reliable, automatable tool helping to identify dead classes. Sure, IDEs tend to claim that certain classes are not used. But if you don't load all modules - that information may or may not be correct. And legacy code with nearly hundreds of modules? Try putting that in your IDE...

The quest for the dead

So, guess what: I actually had (and sometimes still have) to deal with such supposedly dead code. One approach I took to identify such code was setting up a build in our TeamCity instance executing IntelliJ's inspections. Well, there seems to be a limit for everything. I managed to get one finished build out of hundreds of executions. After upgrading to TeamCity 7, builds were finally running. It still took hours to perform the simplest checks (and a bunch of others I just couldn't turn off, as this is a not-that-well-documented feature) and the report came up with many false positives, even such you wouldn't expect: classes being referenced in several Spring XML files, which are perfectly recognized in IntelliJ Idea. Again: there seems to be a limit for everything.

I'm a peaceful mind, but sometimes you need to use brute force. So I wrote a bash script that looped through all classes, removed one, executed a remote run against our continuous integration system, noted the result, reverted the change and went on. Every other day I looked at the results, did a manual double-check (I failed only once), actually removed the dead code, and started the script again.
Even though I did this for only one of our 50+ modules - the one that was set up years ago to contain all the "business logic", having accumulated 2.8k classes over the years - it took me (or, mainly, the script) months to finally run dry (there were whole chains of dead code and the script only recognized one class after the other).  Me & my script managed to eliminate more than 15% of the code base. And I moved another 10% of the code to modules that really needed that classes. Man, I was pumped. And I thought: you're not the only one dealing with legacy code!
But when I decided to open source that thing, I realized that, over the course of months giving the script as little care as a full hour every other week, I could not. Apart from the fact that I don't know bash at all, the script was highly integrated to our build setup and required TeamCity to be executed. As my parental leave was at hand, I left my decision behind.

The missing piece

During that time, some of my co-workers took another approach during the Scout IT Day (our flavor of the FedEx or ShipIt Day) and created a Maven Plugin that chiefly used bytecode analysis to find out if a class was still in usage or not. And that's the starting point for deadcode4j.
deadcode4j is a Maven plugin that aims at finding dead code. It does so using bytecode analysis to find dependencies between code and additionally considers Spring XML files to determine if a class is still in use or not. And this is just the beginning: considering the web.xml, .tld files, @nnotations, and more is in the works.

And how can you use it? Simple: go to the console, navigate to your Maven project, type
  mvn de.is24.mavenplugins:deadcode4j-maven-plugin:find -Dmaven.test.skip=true
and see what it finds.
Hop on over to GitHub to learn more, browse the code, or contribute.
Watch out for announcements, new releases and ideas at sebastiankirsch.blogspot.com