HOW TO: Stereotyping a java Class

In this HowTo post I will show how we can stereotype a class with another class. Why is this useful?

  • When there are a lot of BCI’ing happening in your project, it is not prudent to let every developer write the BCI code.
    • For one, this does not abstract the BCI library used. Thus changing the library itself becomes difficult.
    • BCI is complex. The probability of introducing bugs increase if every developer has to understand BCI.
    • It would be better to write a framework that allows a developer to write an interface and a class which can be used for BCI’ing.
  • Given that java does not support Multiple inheritance, stereotyping can be used to achieve Multiple inheritance without delegating. Check here for multiple inheritance options.
  • There exists aspects of code such as profiling that need to be present only if the code is being tested. Production code is best without being splattered with debug code. Stereotyping can be used in this case by totally varying the classloader used to load the classes, one that adds the profile code and one that does not.

StereoTyping means…

Say there was an interface:

public interface PerfInterface
    public void start(String nm);
    public void end();
    public String getValue(String value);

You write an implementation for this interface:

import java.util.Stack;

public class PerfTemplate implements PerfInterface
    private Stack _stats;

    public void start(String nm)
        PerfStats stat = new PerfStats();
        if (_stats == null)
            _stats = new Stack();


    public void end()
            PerfStats stat = (PerfStats)_stats.pop();
        catch (Exception e)

    public String getValue(String val)
        return "PerfTemplate:Modified:" + val;

You want all classes that need to implement the interface to use the above implementation without a developer actually coding it. At runtime you want the class to adapt this behavior. For eg., you want to code a class as:

public class ClassToStereoType

Which does not implement the PerfInterface. But when running it for performance you want the class to be:

public class ClassToStereoType implements PerfInterface

with all the functions of PerfInterface implemented. This is called stereotyping.

How to Stereotype?

Here we will use the asm library to stereotype. We will follow the same steps as in “BCI during runtime“. We will create a ClassNode object from the class from which we have to stereotype as below:

InputStream nstr = new FileInputStream("PerfTemplate.class");
        ClassReader n = new ClassReader(nstr);
        ClassNode cn = new ClassNode();
        n.accept(cn, ClassReader.EXPAND_FRAMES);

Here we read the class PerfTemplate.class and accept it into a ClassNode which now contains all the fields and methods from PerfTemplate class.

We will write a ClassVisitor that overrides the visitEnd to add the fields and methods from the ClassNode created.

public void visitEnd()
            System.out.println("In visit End. Adding Fields");

            for (Iterator it = _cn.fields.iterator(); it.hasNext();)

            for(Iterator it = _cn.methods.iterator(); it.hasNext();)
                MethodNode mn = (MethodNode);
                if (!"")) //ignore constructor
                    String[] exceptions = new String[mn.exceptions.size()];
                    MethodVisitor mv = cv.visitMethod( mn.access,, mn.desc, mn.signature, exceptions);
                    mn.accept(new RemappingMethodAdapter( mn.access, mn.desc, mv, new SimpleRemapper(, _name)));
            }            super.visitEnd();

In the above code, we iterate through the fields and add it to the class that we are modifying (i.e., ClassToStereoType). When adding the methods we should be careful to ensure all references to PerfTemplate class is modified to ClassToStereoType. For this, we use the RemappingMethodAdapter which is a class provided by asm.

To add the interfaces from PerfTemplate to ClassToStereoType we override the visit method. Here we add the interfaces from the ClassNode to the current class.

public void visit (int version, int access, String name, String signature, String superName, String[] interfaces)
            System.out.println("Class Name is: " + name + ":" + signature + ":" + superName);
            int len = 0;
            List ndeints = _cn.interfaces;
            if (interfaces != null) len = interfaces.length;
            String[] modinterfaces = new String[len + ndeints.size()];
            int cnt = 0;
            for (cnt = 0; (interfaces != null) && ( cnt < interfaces.length); cnt++)
                modinterfaces[cnt] = interfaces[cnt];

            for (String inter : ndeints)
                modinterfaces[cnt++] = inter;
            cv.visit(version, Opcodes.ACC_PUBLIC, name, signature, superName, modinterfaces);
            _name = name;

In the above code, we append all the interfaces from the ClassNode got by calling _cn.interfaces to the interfaces of ClassToStereoType. We use this modified list of interfaces to visit the class. This ensures that the interfaces are implemented in the loaded class.

Now the ClassVisitor implemented with these changes can be used to modify the bytes in the class loader to stereotype the class.

The code for this HOWTO can be found here. Run the commands in to try the sample out.

Reference: HOW TO: Stereotyping a java Class from our JCG partner Raji Sankar at the Reflections blog.
Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

Leave a Reply

1 × one =

Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books