使用byte-buddy的java级别的工具

时间:2018-03-16 13:27:17

标签: java byte-buddy

我有一个Thread Pool示例代码如下

import  Charts


extension BarChartView {

    private class BarChartFormatter: NSObject,IAxisValueFormatter {

        var values : [String]
        required init (values : [String]) {
            self.values = values
            super.init()
        }


        func stringForValue(_ value: Double, axis: AxisBase?) -> String {
            return values[Int(value)]
        }
    }

    func setChartValues (xAxisValues : [String] , values : [Double],label : String) {

        var barChartDataEntries = [BarChartDataEntry]()

        for i in 0..<values.count {
            let dataEntry = BarChartDataEntry(x: Double(i), y: values[i])
            barChartDataEntries.append(dataEntry)
        }
        let chartDataSet = BarChartDataSet(values: barChartDataEntries, label: label)
        chartDataSet.colors = ChartColorTemplates.colorful()
        let chartData = BarChartData(dataSet: chartDataSet)

        let formatter = BarChartFormatter(values: xAxisValues)
        let xAxis = XAxis()
        xAxis.valueFormatter = formatter
        self.xAxis.valueFormatter = xAxis.valueFormatter
        self.xAxis.labelPosition = .bottom

        self.data = chartData
        self.data?.notifyDataChanged()
        self.notifyDataSetChanged()

        self.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .linear)

    }

}

   @IBOutlet weak var barChartView: BarChartView!

    let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
    let unitsSold = [20.0, 4.0, 3.0, 6.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]
    self.barChartView.setChartValues(xAxisValues: months, values: unitsSold, label: "Monthly Sales")

我为仪器java public class RunThreads{ static final int MAX_TASK = 3; public static void main(String[] args) { Runnable r1 = new Task("task 1"); Runnable r2 = new Task("task 2"); Runnable r3 = new Task("task 3"); Runnable r4 = new Task("task 4"); Runnable r5 = new Task("task 5"); ExecutorService pool = Executors.newFixedThreadPool(MAX_TASK); pool.execute(r1); pool.execute(r2); pool.execute(r3); pool.execute(r4); pool.execute(r5); pool.shutdown(); }} 创建一个小代理,如下所示

class Task implements Runnable{
private String name;

public Task(String s)
{
    name = s;
}
public void run()
{
    try
    {
        for (int i = 0; i<=5; i++)
        {
            if (i==0)
            {
                Date d = new Date();
                SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
                System.out.println("Initialization Time for"
                        + " task name - "+ name +" = " +ft.format(d));
                //prints the initialization time for every task
            }
            else
            {
                Date d = new Date();
                SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
                System.out.println("Executing Time for task name - "+
                        name +" = " +ft.format(d));
                // prints the execution time for every task
            }
            Thread.sleep(1000);
        }
        System.out.println(name+" complete");
    }

    catch(InterruptedException e)
    {
        e.printStackTrace();
    }
}}

我们可以使用Byte Buddy来设置类似ThreadPoolExecutor的java类。当我调试ThreadPoolExecutor类工作。但是当我尝试使用代理ThreadPoolExecutor类时,它永远不会工作。

编辑 这是我的MonitorInterceptor

ThreadPoolExecutor

编辑

public class Agent {

public static void premain(String arguments, Instrumentation instrumentation) {

    new AgentBuilder.Default()
            .with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
            .type((ElementMatchers.nameContains("ThreadPoolExecutor")))
            .transform(
                    new AgentBuilder.Transformer.ForAdvice()
                            .include(MonitorInterceptor.class.getClassLoader())
                            .advice(ElementMatchers.any(), MonitorInterceptor.class.getName())
            ).installOn(instrumentation);
}}

2 个答案:

答案 0 :(得分:1)

除非您明确配置它,否则Byte Buddy不会检测核心Java类。您可以通过显式设置不排除此类的忽略匹配器来更改它。

在此上下文中,使用Advice时无需配置初始化策略。

您可能还想限制建议的范围,现在您可以拦截任何方法或构造函数。

为了找出问题所在,您还可以定义一个AgentBuilder.Listener来通知错误。

答案 1 :(得分:1)

使用Rafael Winterhalter回答我解决了这个问题。我创建了一个代理,如下所示,

    $objPHPExcel = new PHPExcel();
    $serialnumber=0;
    $tmparray =array("Sr.Number","Employee ID","Employee Name");
    $sheet =array($tmparray);
    $tmparray =array();
    $serialnumber = $serialnumber + 1;
    array_push($tmparray,$serialnumber);
    $employeelogin = 'aa';
    array_push($tmparray,$employeelogin);
    $employeename = 'bb';
    array_push($tmparray,$employeename);   
    array_push($sheet,$tmparray);
    header('Content-type: application/vnd.ms-excel');
    header('Content-Disposition: attachment; filename="file.xls"');
    $worksheet = $objPHPExcel->getActiveSheet();
    foreach($sheet as $row => $columns) {
        foreach($columns as $column => $data) {
            $worksheet->setCellValueByColumnAndRow($column, $row + 1, $data);
        }
    }
    $objPHPExcel->getActiveSheet()->getStyle("A1:I1")->getFont()->setBold(true);
    $objPHPExcel->setActiveSheetIndex(0);
    $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
    $objWriter->save('php://output');

使用这个我们可以使用Java类。使用这个构造函数来表示这个

new AgentBuilder.Default()
                .ignore(ElementMatchers.none())
                .type(ElementMatchers.nameContains("ThreadPoolExecutor"))
                .transform((builder, type, classLoader, module) -> builder
                        .visit(Advice.to(ThreadPoolExecutorAdvice.class).on(ElementMatchers.any()))
                ).installOn(instrumentation); 

但是在代码构造函数中不是那样的,它是

java.util.concurrent.ThreadPoolExecutor$Worker(java.util.concurrent.ThreadPoolExecutor,java.lang.Runnable)

所以我期待像

这样的东西
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

我使用javassist来获取构造函数并将其作为byte-buddy给出的内容。因此,使用java.util.concurrent.ThreadPoolExecutor(int,int,long,java.util.concurrent.TimeUnit,java.util.concurrent.BlockingQueue) .ignore(ElementMatchers.none()),我们可以获得Java级别类

中的所有构造函数和方法