Dynamic transform
예제 시나리오
- 원하는 작업
- DB에 요청하는 모든 쿼리를 출력
- 작업 순서
- Agent 작성
- ClassFileTransformer 구현
Agent 작성
![]() |
| Java Agent 구성도 |
Manifest 파일
Manifest-Version: 1.0 Premain-Class: sample.bci.Agent Agent-Class: sample.bci.Agent Can-Redefine-Classes: Truemust be end with new line - http://docs.oracle.com/javase/tutorial/deployment/jar/modman.html
Agent.java
/**
* example for bci with java agent
*/
package sample.bci;
import java.lang.instrument.Instrumentation;
/**
* @author k
*
*/
public class Agent {
public static void premain(String args, Instrumentation inst) {
inst.addTransformer(new JdbcQueryTransformer());
}
public static void agentmain(String args, Instrumentation inst) {
inst.addTransformer(new JdbcQueryTransformer());
}
}
JdbcQueryTransformer. java
/**
* example for bci with java agent
*/
package sample.bci;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
/**
* @author k
*
*/
public class JdbcQueryTransformer implements ClassFileTransformer {
public JdbcQueryTransformer() {
super();
}
@Override
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer)
throws IllegalClassFormatException {
byte[] byteCode = classfileBuffer;
ClassPool pool = ClassPool.getDefault();
CtClass currentClass = null;
CtClass statement = null;
try {
currentClass = pool.makeClass(new java.io.ByteArrayInputStream(classfileBuffer));
statement = pool.get("java.sql.Statement");
if (currentClass.subtypeOf(statement) && !currentClass.isInterface()) {
probeStatement(currentClass);
}
byteCode = currentClass.toBytecode();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (currentClass != null) {
currentClass.detach();
}
}
return byteCode;
}
private void probeStatement(CtClass currentClass) throws NotFoundException, CannotCompileException {
CtMethod executeQuery = null;
try {
executeQuery = currentClass.getDeclaredMethod("executeQuery");
} catch (NotFoundException e) {
return;
}
executeQuery.insertBefore("try {System.out.println($1);} catch (Exception e){System.out.println(\"no sql\");}");
}
}
examplecodeusingsql. java
/**
* http://www.tutorialspoint.com/jdbc/jdbc-sample-code.htm
*/
//STEP 1. Import required packages
import java.sql.*;
public class FirstExample {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/EMP";
// Database credentials
static final String USER = "username";
static final String PASS = "password";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
//STEP 2: Register JDBC driver
Class.forName("com.mysql.jdbc.Driver");
//STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql;
sql = "SELECT id, first, last, age FROM Employees";
ResultSet rs = stmt.executeQuery(sql);
//STEP 5: Extract data from result set
while(rs.next()){
//Retrieve by column name
int id = rs.getInt("id");
int age = rs.getInt("age");
String first = rs.getString("first");
String last = rs.getString("last");
//Display values
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", First: " + first);
System.out.println(", Last: " + last);
}
//STEP 6: Clean-up environment
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}finally{
//finally block used to close resources
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
}//end try
System.out.println("Goodbye!");
}//end main

댓글
댓글 쓰기