Ask is moving to Stack Overflow and Serverfault.com! Please use the "opendaylight" tag on either of these sites. This site is now in Read-Only mode

Revision history [back]

click to hide/show revision 1
initial version

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

So, why does this crash and burn? Well... I forgot to include SalService references in my blueprint. So there's no mystery here. What I'm worried about though, is that it took me THIS LONG to find out, that the Preconditions clause did not prevent other parts of the plugin from running, and that the LOG messages I received did not mention such a precondition failure (although I might have been exceptionally unlucky here as for various reasons my Log either did not work or was flooded by exceptions).

Hopefully this will help people for posterity.

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

So, why does this crash and burn? Well... I forgot to include SalService references in my blueprint. So there's no mystery here. What I'm worried about though, is that it took me THIS LONG to find out, that the Preconditions clause did not prevent other parts of the plugin from running, and that the LOG messages I received did not mention such a precondition failure (although I might have been exceptionally unlucky here as for various reasons my Log either did not work failure.

EDIT I definitely do not get warnings from the Precondition check. Worse still, it appears that adding SalFlowService to the blueprint is in itself sufficient to make the registration of my plugin fail! Whether or was flooded by exceptions).

Hopefully not I use the preconditions, if I uncomment the lines in the blueprint, this registration will help people for posterity.

fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

What exactly is going on here? How could those things be related?

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

So, why does this crash and burn? Well... I forgot to include SalService references in my blueprint. So there's no mystery here. What I'm worried about though, is that it took me THIS LONG to find out, that the Preconditions clause did not prevent other parts of the plugin from running, and that the LOG messages I received did not mention such a precondition failure.

EDIT I definitely do not get warnings from the Precondition check. Worse still, it appears that adding SalFlowService to the blueprint is in itself sufficient to make the registration of my plugin fail! Whether or not I use the preconditions, if I uncomment the lines in the blueprint, this registration will fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

What exactly is going EDIT 2 I have effectively made SalFlowService useless in the code, yet its existence in the blueprint file still causes the service registration to fail. At this point, it feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services in the first place. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on here? How could those things be related?

what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch). According to the documentation, it is acceptable to use odl:rpc-service and odl:rpc-implementation (which is what I am doing) in the same blueprint file.

So what's wrong with the blueprint?

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

So, why does this crash and burn? Well... I forgot to include SalService references in my blueprint. So there's no mystery here. What I'm worried about though, is that it took me THIS LONG to find out, that the Preconditions clause did not prevent other parts of the plugin from running, and that the LOG messages I received did not mention such a precondition failure.

EDIT I definitely do not get warnings from the Precondition check. Worse still, it appears that adding SalFlowService to the blueprint is in itself sufficient to make the registration of my plugin fail! Whether or not I use the preconditions, if I uncomment the lines in the blueprint, this registration will fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

EDIT 2 I have effectively made SalFlowService useless in the code, yet its existence in the blueprint file still causes the service registration to fail. At this point, it feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services in the first place. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch). According to the documentation, it is acceptable to use odl:rpc-service and odl:rpc-implementation (which is what I am doing) in the same blueprint file.

So what's wrong with the blueprint?

EDIT 3: Fixed it The blueprint was indeed failing to apply DI correctly, which caused the registration to fail (presumably because if DI fails at any point, it doesn't guarantee to do anything at all). My problem was that I asking for the DI to inject the property "salFlowService", but I did not create a setter:

public void setSalFlowService(SalFlowService salFlowService) {
    this.salFlowService = salFlowService;
}

This meant the DI plugins could not inject anything. If I had used constructor arguments, this would not have been necessary.

Takeaways If anything defined in your blueprint file fails, your blueprint file may end up doing nothing in terms of rpc registration. If you have a call to "Preconditions.checkNotNull" which fails, rpc registration might also fail for some reason.

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

So, why does this crash and burn? Well... I forgot to include SalService references in my blueprint. So there's no mystery here. What I'm worried about though, is that it took me THIS LONG to find out, that the Preconditions clause did not prevent other parts of the plugin from running, and that the LOG messages I received did not mention such a precondition failure.

EDIT I definitely do not get warnings from the Precondition check. Worse still, it appears that adding SalFlowService to the blueprint is in itself sufficient to make the registration of my plugin fail! Whether or not I use the preconditions, if I uncomment the lines in the blueprint, this registration will fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

EDIT 2 I have effectively made removed SalFlowService useless in from the code, yet its existence in the blueprint file still causes the service registration to fail. At this point, it It feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services in the first place. services. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch). According to the documentation, it is acceptable to use odl:rpc-service and odl:rpc-implementation (which is what I am doing) in the same blueprint file.l2Switch).

EDIT 3: Fixed it The blueprint was indeed failing to apply DI correctly, which caused the registration to fail (presumably because if DI fails at any point, it doesn't guarantee to do anything at all). My problem was that I asking for the DI to inject the property "salFlowService", but I did not create a setter:

public void setSalFlowService(SalFlowService salFlowService) {
    this.salFlowService = salFlowService;
}

This meant the DI plugins could not inject anything. If I had used constructor arguments, this would not have been necessary.

Takeaways If anything defined in your blueprint file fails, your blueprint file may end up doing nothing in terms of rpc registration. If you have a call to "Preconditions.checkNotNull" which fails, rpc registration might also fail for some reason.

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

So, why does this crash and burn? Well... I forgot to include SalService references in my blueprint. So there's no mystery here. What I'm worried about though, is that it took me THIS LONG to find out, that the Preconditions clause did not prevent other parts of the plugin from running, and that the LOG messages I received did not mention such a precondition failure.

EDIT I definitely do not get warnings from the Precondition check. Worse still, it appears that adding Adding SalFlowService to the blueprint is in itself sufficient to make the registration of my plugin fail! Whether or not I use the preconditions, if I uncomment fail. Uncommenting the lines in the blueprint, this makes the registration will fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

EDIT 2 I removed SalFlowService from the code, yet its existence in the blueprint file causes the service registration to fail. It feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch).

EDIT 3: Fixed it The blueprint was indeed failing to apply DI correctly, which caused the registration to fail (presumably because if DI fails at any point, it doesn't guarantee to do anything at all). My problem was that I asking for the DI to inject the property "salFlowService", but I did not create a setter:

public void setSalFlowService(SalFlowService salFlowService) {
    this.salFlowService = salFlowService;
}

This meant the DI plugins could not inject anything. If I had used constructor arguments, this would not have been necessary.

Takeaways If anything defined in your blueprint file fails, your blueprint file may end up doing nothing in terms of rpc registration. If you have a call to "Preconditions.checkNotNull" which fails, rpc registration might also fail for some reason.

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

So, why does this crash and burn? Well... It turns out I forgot to include SalService SalFlowService references in my blueprint. So there's no mystery here. What I'm worried about Worryingly, though, is that it took me THIS LONG to find out, that the Preconditions clause did not prevent other parts of the plugin from running, and that the LOG messages I received did not mention such a precondition failure.yet no LOGs were received, making the failure completely opaque.

EDIT I not get warnings from the Precondition check. Adding SalFlowService to the blueprint is sufficient to make the registration fail. Uncommenting the lines in the blueprint, makes the registration fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

EDIT 2 I removed SalFlowService from the code, yet its existence in the blueprint file causes the service registration to fail. It feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch).

EDIT 3: Fixed it The blueprint was indeed failing to apply DI correctly, which caused the registration to fail (presumably because if DI fails at any point, it doesn't guarantee to do anything at all). My problem was that I asking for the DI to inject the property "salFlowService", but I did not create a setter:

public void setSalFlowService(SalFlowService salFlowService) {
    this.salFlowService = salFlowService;
}

This meant the DI plugins could not inject anything. If I had used constructor arguments, this would not have been necessary.

Takeaways If anything defined in your in the blueprint file fails, your blueprint file it may end up doing do nothing in terms of rpc registration. If you have a call to "Preconditions.checkNotNull" which fails, rpc registration might also fail for some reason.

fail. If registration fails, logging my also not work.

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

It turns out I forgot to include SalFlowService references in my blueprint. Worryingly, though, the Preconditions clause did not prevent other parts of the plugin from running, yet no LOGs were received, making the failure completely opaque.

EDIT Adding SalFlowService to the blueprint is sufficient to make the registration fail. Uncommenting the lines in the blueprint, makes the registration fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

EDIT 2 I removed SalFlowService from the code, yet its existence in the blueprint file causes the service registration to fail. It feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch).

EDIT 3: Fixed it The blueprint was indeed failing to apply DI correctly, which caused the registration to fail (presumably because if DI fails at any point, it doesn't guarantee to do anything at all). blueprint parsing immediately stops). My problem was that I asking for the DI to inject the property "salFlowService", but I did not create a setter:

public void setSalFlowService(SalFlowService salFlowService) {
    this.salFlowService = salFlowService;
}

This meant the DI plugins could not inject anything. If I had used constructor arguments, this would not have been necessary.

Takeaways If anything in the blueprint fails, it may do nothing in terms of rpc registration. If a call to "Preconditions.checkNotNull" fails, rpc registration might also fail. If registration fails, logging my also not work.

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

It turns out I forgot to include SalFlowService references in my blueprint. Worryingly, though, the Preconditions clause did not prevent other parts of the plugin from running, yet no LOGs were received, making the failure completely opaque.

EDIT Adding SalFlowService to the blueprint is sufficient to make the registration fail. Uncommenting the lines in the blueprint, makes the registration fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

EDIT 2 I removed SalFlowService from the code, yet its existence in the blueprint file causes the service registration to fail. It feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch).

EDIT 3: Fixed it The blueprint was indeed failing to apply DI correctly, which caused the registration to fail (presumably because if DI fails at any point, blueprint parsing immediately stops). My problem was that I asking asked for the DI to inject the property "salFlowService", but I did not create a setter:

public void setSalFlowService(SalFlowService salFlowService) {
    this.salFlowService = salFlowService;
}

This meant the DI plugins could not inject anything. anything, leading to failure. If I had used constructor arguments, this would not have been necessary.

Takeaways If anything in the blueprint fails, it may do nothing in terms of rpc registration. If a call to "Preconditions.checkNotNull" fails, rpc registration might also fail. If registration fails, logging my also not work.

Answering my own question.

I went back to the early steps of my code where I recalled that the RPC methods were registering correctly. I slowly rebuilt my code up to the current state, incrementally verifying that the added changes were not the changes that broke the RPC registration. I singled out the one line in the init method:

public void init() {
    LOG.info("Initializing...");
    registerAsDataChangeListener(dataBroker);
    // THIS LINE: Preconditions.checkNotNull(salFlowService, "sal flow service must be set");
    Preconditions.checkNotNull(notificationProvider, "notification provider must be set");
    Preconditions.checkNotNull(dataBroker, "dataBroker must be set");
    allNodes = getAllNodes();
    hashFlowInstaller = new HashFlowInstaller(LOG, salFlowService);
    LOG.debug("Got all nodes: {}", allNodes.size());
}

Indeed, with this line, the RPC call is NOT registered, and without this line, the RPC call IS registered. Presumably there were other glitches in my code, but I have boiled it down to this.

It turns out I forgot to include SalFlowService references in my blueprint. Worryingly, though, the Preconditions clause did not prevent other parts of the plugin from running, yet no LOGs were received, making the failure completely opaque.

EDIT Adding SalFlowService to the blueprint is sufficient to make the registration fail. Uncommenting the lines in the blueprint, makes the registration fail:

  <!-- <odl:rpc-service id="salFlowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService" /> -->

  <!-- Create the OpendaylightToaster instance and inject its dependencies -->
  <bean id="hashLoadBalancerManagerImpl" class="edu.ulaval.sdn.hashloadbalancermanager.HashLoadBalancerManagerImpl" init-method="init" destroy-method="close">
    <property name="dataBroker" ref="dataBroker"/>
    <property name="notificationProvider" ref="notificationService"/>
    <!-- <property name="salFlowService" ref="salFlowService" /> -->
  </bean>

EDIT 2 I removed SalFlowService from the code, yet its existence in the blueprint file causes the service registration to fail. It feels to me that the culprit is the blueprint file, as it is responsible for registering rpc services. If including salFlowService makes the blueprint processing fail, it would explain why the rpc registration failed in the first place. I am not entirely clear on what "odl:rpc-service" does here. I am using it only because that is how salFlowService is being imported in other segments of ODL's code (e.g. l2Switch).

EDIT 3: Fixed it The blueprint was indeed failing to apply DI correctly, which caused the registration to fail (presumably because if DI fails at any point, blueprint parsing immediately stops). My problem was that I asked for the DI to inject the property "salFlowService", but I did not create a setter:

public void setSalFlowService(SalFlowService salFlowService) {
    this.salFlowService = salFlowService;
}

This meant the DI plugins could not inject anything, leading to failure. If I had used constructor arguments, this would not have been necessary.

Takeaways If anything in the blueprint fails, it may do nothing in terms of rpc registration. If a call to "Preconditions.checkNotNull" fails, rpc registration might also fail. If registration fails, logging my also may not work.