Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Java Holiday Calendar 2016 (Day 16): Hacking the Existing Java Classes

DZone's Guide to

Java Holiday Calendar 2016 (Day 16): Hacking the Existing Java Classes

Get your black hat - it's time to hack some classes. But because everyone follows the rules, this tip will help squash third-party bugs and deal with non-standard classes.

· Java Zone
Free Resource

The single app analytics solutions to take your web and mobile apps to the next level.  Try today!  Brought to you in partnership with CA Technologies

Image title

Today's tip is about hacking the existing Java classes. But before we start, I would like to issue a disclaimer: I am only showing this to illustrate certain possibilities. This post contains code that is against best-practice and also a number of license terms for commercial JVMs, and I would discourage anyone from using this for purposes other than just experimenting in dark cellars at late nights.

The Task

There is a lot of magic going around with auto-boxing and instance caching with wrapper classes like java.lang.Integer. Suppose we could hack the Integer class so it will keep track of how many of its instances are created and how many instances are garbage collected. And what if we could add a way of retrieving these statistics in some form? How do we go about?

Open Sesame

The JVM has a command line parameter named "-Xbootclasspath/p:" that can be used to load Java classes before the standard java classes are loaded. This way, we can inject our own versions of Java classes before the real ones load.

This is also useful for other classes that are not a part of the standard Java library. If there is a bug in a third-party product, we can correct the bug and just load the correct version before the app loads. It also enables us to instrument classes so they, for example, can collect usage statistics or introduce or prevent certain things from happening.

Hacking the Integer Class

Create a custom class named Integer and place that in a package named java.lang. Retrieve the standard source code of Integer from the JDK and copy that into the custom java.lang.Integer class.

Add the following at the beginning of the copied Integer class:

public static final AtomicLong INSTANCE_CREATE_COUNTER = new AtomicLong();

public static final AtomicLong INSTANCE_FINALIZE_COUNTER = new AtomicLong();


Modify the constructor like this:

public Integer(int value) {
    this.value = value;
    INSTANCE_CREATE_COUNTER.incrementAndGet();
}


Finally, add the following method:

@Override
protected void finalize() throws Throwable {
    INSTANCE_FINALIZE_COUNTER.incrementAndGet();
}


That's it! We have hacked the Integer class. The modified class can now be used like this:

package org.darkside.hack;
public class Main {
    public static void main(String[] args) {
        printIntegerInstanceInfo();
        Integer i = 456;
        printIntegerInstanceInfo();
        System.gc();
        sleep(1000);
        printIntegerInstanceInfo();
    }
    public static void printIntegerInstanceInfo() {
        long create = Integer.INSTANCE_CREATE_COUNTER.get();
        long finalized = Integer.INSTANCE_FINALIZE_COUNTER.get();
        System.out.format(
            "The JVM has created %d instances and finalized %d instances of Integer."
                + " Thus, %d instances are on the heap.%n",
            create,
            finalized,
            create - finalized
        );
    }

    public static void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException ie) {
        }
    }
}


Running the Code

The code can be run like this:

java -Xbootclasspath/p:hack_java_class-1.0.0-SNAPSHOT.jar org.darkside.hack.Main


We have to change the name of the .jar file depending on how we named our artifact. Make sure that the modified Integer class and the Main class resides in the same jar. We can also have the modified classes in a separate jar but then we need to add the other parts using the normal class path commands.

Wrap Up

The notion here is "Don't Try This at Home." That said, we can learn a lot by injecting custom classes into the JVM.

There are many better ways of keeping track of how many instances that are created and destroyed by the JVM. The task in this post is just for the sake of reasoning.

Be careful out there!

CA App Experience Analytics, a whole new level of visibility. Learn more. Brought to you in partnership with CA Technologies.

Topics:
java ,java security ,custom classes ,hacking

Published at DZone with permission of Per-Åke Minborg, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}