Git Product home page Git Product logo

Comments (6)

jbachorik avatar jbachorik commented on July 4, 2024

[author="joachimhskeie", created="Sat, 19 Mar 2011 23:12:41 +0100"]

Attaching half the story. The plugin architecture is in place, and BTrace is able to call a plugin's "process()" method based on the plugin name. Whats missing here is a way for BTrace to inject a callback into the plugin, so that the plugin can actually do something useful.

I'm not quite sure on the best approach here:

1. Implementing services for different types of callbacks (one for settings/info, one for executing methods from BTraceUtils, etc). ?
2. Give the plugin a reference to BTraceUtils (or another central class) ?
3. Create an interface in btrace-api that exposes a selected amount of methods from BTraceUtils, which can then be injected into the plugins ?
4. Other options/ideas ?

from btrace.

jbachorik avatar jbachorik commented on July 4, 2024

[author="joachimhskeie", created="Mon, 21 Mar 2011 22:32:05 +0100"]

As BTraceUtils is a collection of static methods, neither an interface not an abstract class can be used to represent a puplic api to BTraceUtils, so I'm not entirely sure how its possible to expose methods from BTraceUtils without actually exposisg the whole class.

Any ideas here ?

from btrace.

jbachorik avatar jbachorik commented on July 4, 2024

[author="joachimhskeie", created="Wed, 23 Mar 2011 21:38:15 +0100"]

Attaching the second half of the story. I have created an abstract class in btrace-api called BTraceService. This class is implemented in btrace-core in a class called BTraceServiceImpl (lack of a better name). In addition, I added a setter-method to the plugin, allowing the BTrace pluginmanager to inject a the dependency to BtraceServiceImpl.

The main reason for making BTraceService an abstract class (instead of an interface) is to have more control over backwards-compatibility. If the base class is an abstract class, then a plugin will work, even though it is compiled against an earlier version of BTrace (as long as method signatures havent changed, and methods have only been added).

As a first go, I enabled BTraceService to call both print and println from BTraceUtil. As the plugin I am writing needs access to the agent argument map, I also added a means to store and get hold of this from BTraceRuntime.

In my opinion, having this type of pluginability to BTrace might really enhance what third parties are able to do with BTrace.

Creating a new Plugin could be as simple as:

package org.eurekaj.proxy;
import com.sun.btrace.api.BTraceService;
import com.sun.btrace.spi.BTraceProcessProvider;
import org.eurekaj.proxy.parser.ParseStatistics;
import org.eurekaj.webservice.StoreIncomingStatisticsElement;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
 * Created by IntelliJ IDEA.
 * User: jhs
 * Date: 3/18/11
 * Time: 3:22 PM
 * To change this template use File | Settings | File Templates.
 */
public class RemoteJsonPlugin implements BTraceProcessProvider {
    private BTraceService bTraceService;
    @Override
    public String getPluginName() {
return "RemoteJsonPlugin";
    }
    @Override
    public void process() {
if (bTraceService != null && bTraceService.getAgentArgument("scriptdir") != null) {
    bTraceService.println("Printing from Plugin: " + getPluginName());
    List scriptOutputfileList = FileMatcher.getScriptOutputFilesInDirectory(bTraceService.getAgentArgument("scriptdir"));
    for (File scriptOutputFile : scriptOutputfileList) {
try {
    List statElemList = ParseStatistics.parseBtraceFile(scriptOutputFile);
    bTraceService.println("File: " + scriptOutputFile.getAbsolutePath() + " has " + statElemList.size() + " statistics.");
    scriptOutputFile.delete();
} catch (IOException e) {
    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
}
    }
}
    }
    @Override
    public void setBtraceService(BTraceService bTraceService) {
this.bTraceService = bTraceService;
    }
}

This plugin is executed by the following BTrace script:

@OnTimer(15000)
    public static void printMem() {
        Plugins.executePluginWithName("RemoteJsonPlugin");
    }

from btrace.

jbachorik avatar jbachorik commented on July 4, 2024

[author="joachimhskeie", created="Wed, 23 Mar 2011 21:48:53 +0100"]

Updating the architecture drawing of the plugin-architecture

from btrace.

jbachorik avatar jbachorik commented on July 4, 2024

[author="j.bachorik", created="Wed, 23 Mar 2011 23:05:39 +0100"]

See my comment in the forum

from btrace.

jbachorik avatar jbachorik commented on July 4, 2024

Update

As I wrote in my blog the extensive changes I did for the proposed BTrace 2 to bring in modularity didn't seem to be warmly received.

Therefore I came up with a simpler proposal to introduce the way to extend the core BTrace functionality via plugins which would give up on pretending that the extensions would be safe and rely only on the good manners of the extension authors and common sense of the extension users.

Architecture

The basic unit becomes a service. A service can be referenced from the script and performs specific operations extending the basic BTrace capabilities.

Implementing a service

In order to create a new service one would extend one of these two classes

  • com.sun.btrace.services.spi.SimpleService - for simple stateless servicess (or singletons)
  • com.sun.btrace.services.spi.RuntimeService - for runtime aware services

Using a service

First, the all the jars containing services one wants to use must be defined as an extension to the boot classpath.

Services can be accessed by:

  • annotating a field by @injected annotation
    /class level/
    @injected private static MySimpleService s1;
    @injected(ServiceType.RUNTIME) private static MyRuntimeService s2;
    @injected(factoryMethod = "singleton") private static MySimpleService s3;

    /method level/
    s1.doSomething();
    s2.doSomethingElse();
    s3.doSomething();

  • instantiating a local variable by using one of the Service.(simple|runtime) factory methods
    /method level/
    MySimpleService s1 = Service.simple(MySimpleService.class);
    MyRuntimeService s2 = Service.runtime(MyRuntimeService.class);
    MySimpleService s2 = Service.simple("singleton", MySimpleService.class);

from btrace.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.