/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2012, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.instrumentation; import javassist.ClassPool; import javassist.CtClass; import org.helios.apmrouter.util.SimpleLogger; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.lang.reflect.Modifier; import java.security.ProtectionDomain; /** * <p>Title: SocketStreamClassTransformer</p> * <p>Description: Modifies accessors on socket input and output streams</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.instrumentation.SocketStreamClassTransformer</code></p> */ public class SocketStreamClassTransformer implements ClassFileTransformer { public static final String SOS = "java/net/SocketOutputStream"; /** * {@inheritDoc} * @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader, java.lang.String, java.lang.Class, java.security.ProtectionDomain, byte[]) */ @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { ClassPool tClassPool = null; try { if(SOS.equals(className)) { tClassPool = new ClassPool(); tClassPool.appendSystemPath(); CtClass clazz = tClassPool.get("java.net.SocketOutputStream"); clazz.setModifiers(clazz.getModifiers() | Modifier.PUBLIC); byte[] byteCode = clazz.toBytecode(); SimpleLogger.info("\n\tGenerated Byte Code for [" , clazz.getName(), "]\n"); return byteCode; } } catch (Throwable ex) { SimpleLogger.warn("Failed to instrument [", className, "]", ex); return classfileBuffer; } return classfileBuffer; } /** * Converts a class name to the binary name used by the class file transformer, or returns the passed name if it is already a binary name * @param name The class name to convert * @return the binary name */ protected String convertToBinaryName(String name) { int index = name.indexOf('.'); if(index!=-1) { return name.replace('.', '/'); } return name; } /** * Converts a class name from the binary name used by the class file transformer to the standard dot notated form, or returns the passed name if it is already a binary name * @param name The class name to convert * @return the standard dot notated class name */ protected String convertFromBinaryName(String name) { int index = name.indexOf('/'); if(index!=-1) { return name.replace('/', '.'); } return name; } }