1

Below is my CuratorClient class which is connecting to Zookeeper and starting the leader election process as well.

public class CuratorClient {

    // can I make this as static?
    private static CuratorFramework client;
    private String latchPath;
    private String id;
    private LeaderLatch leaderLatch;

    public CuratorClient(String connString, String latchPath, String id) {
        client = CuratorFrameworkFactory.newClient(connString, new ExponentialBackoffRetry(1000, Integer.MAX_VALUE));
        this.id = id;
        this.latchPath = latchPath;
    }

    public void start() throws Exception {
        client.start();
        client.getCuratorClient().blockUntilConnectedOrTimedOut();
        leaderLatch = new LeaderLatch(client, latchPath, id);
        leaderLatch.start();
    }

    public boolean isLeader() {
        return leaderLatch.hasLeadership();
    }

    public Participant currentLeader() throws Exception {
        return leaderLatch.getLeader();
    }

    public void close() throws IOException {
        leaderLatch.close();
        client.close();
    }

    // can I use below method from any other class ?
    protected static List<String> getChildren(String node) throws Exception {
        return client.getChildren().forPath(node);
    }
}

When my service gets started up, in the static block I am making a connection to Zookeeper using CuratorClient and starting the leader election process as well.

public class TestService {

    private static CuratorClient curatorClient = null;
    static {

        try {
            String connectionString = "some-string";
            String hostname = "machineA";

            curatorClient = new CuratorClient(connectionString, "/my/latch", hostname);
            curatorClient.start();

        } catch (Exception ex) {
            // log exception
        }
    }

    ....
    ....

    // some method
    public Map<String, String> installNewSoftware(String node) {

    //.. some other code
    try {
        List<String> children = CuratorClient.getChildren("/my/example");
        System.out.println(children);

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

    //.. some other code
    return null;
    }
}

Now I have some other class as well which likes to use the getChildren method of CuratorClient so in this class, I can directly use like this CuratorClient.getChildren("/my/example"); correct?

public class DifferentClass {

    ....
    ....

    // some new method
    public Map<String, String> installNewSoftware(String node) {
    try {
        List<String> children = CuratorClient.getChildren("/my/example");
        System.out.println(children);

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

    //.. some other code
    return null;
    }
}

In general, this is not a curator question or zookeeper question. It's basically a design question and I am trying to understand whether the way I am doing it will have any problem or not? And I am assuming CuratorFramework will be thread safe as well?

  • Why shouldn't you? Utility-classes are all build this way. EDIT: Of course the method and the class should be public. – Alexander_Winter Feb 20 '14 at 19:47
  • You can't call the method from another class (that is not a subclass) because the method is `protected`. A `protected` method may only be called from the owning class or a subclass of the owning class. – Hot Licks Feb 20 '14 at 19:47
  • Also, of course, if you were able to call that method (because it was declared `public`), it would still be referencing the `client` static field of `CuratorClient`, which may or may not be what you want. – Hot Licks Feb 20 '14 at 19:49
  • @HotLicks: That's what I am not sure- `static field of CuratorClient, which may or may not be what you want.` This is what confusing me a lot. My main job is to get the children of a particular node from the Zookeeper using Curator library and I am building this utility so that I can call it from different class as well just by passing which node children I need to get. –  Feb 20 '14 at 19:55
  • It's hard to call without studying the app in some detail. – Hot Licks Feb 20 '14 at 20:00
  • Reading this [documentation](http://curator.apache.org/curator-framework/) it says `CuratorFramework` instances are thread safe. So I guess I can use it static sense correct? Read this in that link - `IMPORTANT: CuratorFramework instances are fully thread-safe. You should share one CuratorFramework per ZooKeeper cluster in your application.` –  Feb 20 '14 at 20:10

1 Answers1

2

Yes, you can call static methods from other classes.

Your signature looks like this:

protected static List<String> getChildren(String node) throws Exception

The reason you can't call this from another class is because it's protected (visible to the current class and subclasses) instead of public (visible to everywhere).

If you make it visible you can call it with CuratorClient.getChildren().

More information on access modifiers.
More information on class members (static fields).

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
  • Thanks Jeroen for the suggestion.. Now if I am calling it this way then will I be having any issues as it is declared as static? And `getChildren` method will go and get the children of a node from Zookeeper schema? –  Feb 20 '14 at 19:53
  • I don't have a compiler built in my head (yet) so the best way to test this is by executing your program and see what happens. After observing the results of this you can look into possible causes and draw conclusions. Having a field as `static` means that every instance of your object will refer to the same instance of your object in the `static` field. Sometimes this is what you want, sometimes it isn't: that's up to you. I can't possibly tell what `getChildren()` will do since I don't have the code for that (execute it, you'll see yourself what it does). – Jeroen Vannevel Feb 20 '14 at 19:57
  • Reading this [documentation](http://curator.apache.org/curator-framework/) it says `CuratorFramework` instances are thread safe. So I guess I can use it static sense correct? Read this in that link - `IMPORTANT: CuratorFramework instances are fully thread-safe. You should share one CuratorFramework per ZooKeeper cluster in your application.` –  Feb 20 '14 at 20:09