Jeta providers an implementation of Publish-Subscribe pattern. Besides basic features, it has a great advantage - no reflection is used at all. Excited? Let’s go through.


class Subscriber {
    private SubscriptionHandler handler;

    public Subscriber() {
        handler = MetaHelper.registerSubscriber(this);

    protected void onMessage(Message msg) {

As well as observer’s handler, SubscriptionHandler lets you control subscription workflow. You can stop listening to a message:


or all of them:



You’re able to order the handlers by priority. Handlers with higher priority will be invoked first:

@Subscribe(priority = 146)
protected void onMessage(Message msg) {


Jeta Event-Bus supports filters, so you can reject unwanted messages:

@Subscribe(filters = { OddFilter.class })
protected void onMessage(Message msg) {

For the illustration, OddFilter code is:

public class OddFilter implements Filter<Object, MyMessage> {
    public boolean accepts(Object master, String methodName, MyMessage msg) {
        return % 2 != 0;

Two filters are available out of the box, by id and by topic. You can define them via @Subscribe annotation:

@Subscribe(id = {2, 4}, topic = {"two", "four"})
protected void onMessage(Message msg) {

Note To make id and topic filters possible, all messages must implement org.brooth.jeta.eventbus.Message interface or extend org.brooth.jeta.eventbus.BaseMessage class.


As previously mentioned, Jeta is designed to detect as many errors at compile-time as possible . With plain filters this principle works via generic types. Let’s say we have a filter that works with a particular message type:

public class MyMessage extends BaseMessage {

public class MyFilter implements Filter<Object, MyMessage> {
    public boolean accepts(Object master, String methodName, Message msg) {
        return true;

If you try to use this filter on a method with a parameter which not assigneble from MyMessage class, the code won’t be compiled, but MetaFilters allow you to write more complex checks, e.g. access to a nonprivate constant:

@MetaFilter(emitExpression = "$m.THE_NUMBER % 2 == 0")
public interface EvenMetaFilter extends Filter {}

Here $m will be replaced with the master class in which this filter is used. So if the master doesn’t have field THE_NUMBER, you will get the error during compilation. You can also use $e to get access to the message instance.


You can either use Jeta basic implementation of EventBus - org.brooth.jeta.eventbus.BaseEventBus or implement your own. Also, you can use a single instance of the bus or create many. Nevertheless, you must pass an instance of the bus to the controller. Let’s create a helper method for:

public static SubscriptionHandler registerSubscriber(Object master) {
    return new SubscriberController<>(metasitory, master).registerSubscriber(bus);

You definitely should follow this link if you are still not familiar with MetaHelper.

How it works:

User's Guide:



Stable version: 2.3
Available on Java 1.7+
Android Compatible
Fork me on GitHub