1

I am trying to inject some additional code to each method using a Java agent. So far I am writing the code something like this:

String signature = method.getSignature();
method.insertBefore("System.err.println(\"" + signature + "\");");

Is there a cleaner way of writing Java syntax? Something similar to the one available for SQL would be useful.

Update: For example, to create System.err.println, something like createClass("System").createField("out").createMethod("println").

Community
  • 1
  • 1
Arani
  • 400
  • 6
  • 21

2 Answers2

1

I believe you are looking for String.format(String, Object...) and something like

method.insertBefore(String.format("System.err.println(\"%s\");", signature));
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • Something similar, but being able to get rid of the escaped quotes will be better. – Arani Aug 02 '15 at 05:53
  • 1
    Either use single quotes ( ' ) or try externalization, then you can define your messages in a text file and there you don't need to escape quotes. Inside Java code, you need them. – Florian Schaetz Aug 02 '15 at 06:01
  • @FlorianSchaetz I understand what you are saying. What I am looking for is some utility library that handles this for me. For example, defineClass("System").defineField("out").defineFunction("println"). Something like this will be useful – Arani Aug 02 '15 at 06:08
1

You can do it yourself as a utility :

package ramin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import com.google.common.base.Joiner;

public class AraniUtil{

    private StringBuilder fullyQualifiedName = new StringBuilder("");//fully qualified name

    /*
     * Parameters :
     * List classes : a list of classes to build in String type
     * List fields : a list of fields to build in String type
     * HashMap<String, List> methodsAndSignatures (or "mas") : a hashmap where maps method name to a list of arguments in String Type
     */
    public AraniUtil(List classes, List fields, HashMap<String, List> mas)
    {
        //list of manipulated methods with their arguments
        List methods = new ArrayList();
        Iterator iterator = mas.keySet().iterator();//method names iterator
        for (Iterator i = iterator; iterator.hasNext(); ) {

            Object next = i.next();
            StringBuilder mapped = new StringBuilder("");
            mapped.append((String) next);


            Iterator signatures = mas.get(next).iterator();
            List tempSignature = new ArrayList();
            for (Iterator j = signatures; j.hasNext(); ) {
                next = j.next();
                if (next.getClass().equals(String.class))
                    //mapped.append("\"" + next + "\"");
                    tempSignature.add("\"" + next + "\"");
                else
                    tempSignature.add(next);
                    //mapped.append(next);
            }
            mapped.append("(" + Joiner.on(",").join(tempSignature) + ")");
            methods.add(mapped.toString());
        }
        fullyQualifiedName.append(Joiner.on(".").join(classes) + ".");
        fullyQualifiedName.append(Joiner.on(".").join(fields) + ".");
        fullyQualifiedName.append(Joiner.on(".").join(methods));
    }

    @Override
    public String toString(){
        return this.fullyQualifiedName.toString();
    }

    public static void main(String[] args) {
        //initializing classes to create
        List classes = new ArrayList<String>();
        classes.add("System");
        classes.add("System2");
        //initializing fields to create
        List fields = new ArrayList<String>();
        fields.add("out");
        fields.add("out2");
        HashMap methodsAndSignatures = new HashMap();
        //creating method signatures
        List tempList = new ArrayList();
        tempList.add("arg1");
        tempList.add(6956);
        //map a method to array of arguments
        methodsAndSignatures.put("println", tempList);
        //creating method signatures
        List tempList2 = new ArrayList();
        tempList2.add("arg2");
        tempList2.add(6956555);
        //map a method to array of arguments
        methodsAndSignatures.put("println2", tempList2);
        //actual utility function
        AraniUtil araniUtil = new AraniUtil(classes, fields, methodsAndSignatures);
        //and the result
        System.out.println(araniUtil);
    }
}

I've written this my self and encourage my friends to refactor/edit it.

This outputs System.System2.out.out2.println("arg1",6956).println("arg2",6956555)

This works perfectly :)

Ramin Omrani
  • 3,673
  • 8
  • 34
  • 60