0

I made some changes per suggestions from another question to turn my class into a @Singleton rather than @Stateless, however I'm no longer receiving messages in my @MessageDriven Bean as I was before. Suggestions? Note that the topic is correctly defined in jbossmq-destinations-service.xml

@javax.ejb.Singleton(mappedName="MySingletonClass")
public class MySingletonClass implements SomeInterface
{
   private Timer timer = null;

   @javax.annotation.Resource
   TimerService timerService;


   /**
    * Creates the timer.
    */
   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public void resetTimer()
   {
      if (timer != null)
      {
         timer.cancel();
      }
      timer = timerService.createTimer(30000, "Note");
   }

   @Override
   public void readResponseMsg(Document responseXml)
   {
      resetTimer();
      //Do stuff
   }

   @Override
   @Timeout
   public void timeout() throws RemoteException
   {
       //do stuff
   }
}

and the MDB:

@javax.ejb.MessageDriven(mappedName = "jms/MyTopic", activationConfig = {
      @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
      @ActivationConfigProperty(propertyName = "destination", propertyValue = "MyTopic"),
      @ActivationConfigProperty(propertyName = "messagingType", propertyValue = "javax.jms.MessageListener"),
      @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })
@ResourceAdapter("activemq.rar")
public class MyMDB implements MessageListener
{
   private static final Logger ourLogger = Logger.getLogger(MyMDB.class);

   @javax.ejb.EJB(mappedName="MySingletonClass") private MySingletonClassInterface reader;

   /**
    * @param message
    */
   public void onMessage(Message message)
   {
      TextMessage textMessage = (TextMessage) message;
      try
      {
         System.out.println("Received Message Text: " + textMessage.getText());
         reader.readResponseMsg(loadXMLFromString(textMessage.getText()));
      }
      catch (JMSException | SAXException | ParserConfigurationException | IOException e)
      {
         ourLogger.error("Exception handling Schedule Results Message", e);
      }
   }
}

This is the interface:

@javax.ejb.Local
public interface SomeInterface
{
   public void readResponseMsg(Document responseXml);


   public void timeout() throws RemoteException;
}

UPDATE I've been fiddling with some things and am now seeing some exceptions that at least indicate something is happening. I've updated the code above with my changes. This is my exception:

Caused by: javax.naming.NameNotFoundException: MySingletonClass not bound
    at org.jnp.server.NamingServer.getBinding(NamingServer.java:771) [:5.0.5.Final]
    at org.jnp.server.NamingServer.getBinding(NamingServer.java:779) [:5.0.5.Final]
    at org.jnp.server.NamingServer.getObject(NamingServer.java:785) [:5.0.5.Final]
    at org.jnp.server.NamingServer.lookup(NamingServer.java:396) [:5.0.5.Final]
    at org.jnp.server.NamingServer.lookup(NamingServer.java:399) [:5.0.5.Final]
    at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:728) [:5.0.5.Final]
    at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:688) [:5.0.5.Final]
    at javax.naming.InitialContext.lookup(InitialContext.java:411) [:1.7.0_25]
    at org.jnp.interfaces.NamingContext.resolveLink(NamingContext.java:1350) [:5.0.5.Final]
    ... 61 more

Also, further up in the JBoss 6 startup log, I am also seeing this:

 [BeanInstantiatorDeployerBase] Installed org.jboss.ejb3.instantiator.impl.Ejb31SpecBeanInstantiator@fbda95 into MC at org.jboss.ejb.bean.instantiator/mmpl/server/MySingletonClass

then a little further down the log:

DEPLOYMENTS MISSING DEPENDENCIES:
  Deployment "jboss-switchboard:appName=mmpl,module=server,name=MyMDB" is missing the following dependencies:
   Dependency "jboss.j2ee:ear=mmpl.ear,jar=server.jar,name=MySingletonClass,service=EJB3" (should be in state "Installed", but is actually in state "** NOT FOUND Depends on 'jboss.j2ee:ear=mmpl.ear,jar=server.jar,name=MySingletonClass,service=EJB3',whenRequired=MapControllerStateModel$ControllerStateWrapper@7ba014{Installed},dependentState=MapControllerStateModel$ControllerStateWrapper@7ba014{Installed} **")
  Deployment "jboss.j2ee:ear=mmpl.ear,jar=server.jar,name=MySingletonClass,service=EJB3_endpoint" is missing the following dependencies:
    Dependency "jboss.j2ee:ear=mmpl.ear,jar=server.jar,name=MySingletonClass,service=EJB3" (should be in state "Installed", but is actually in state "** NOT FOUND Depends on 'jboss.j2ee:ear=mmpl.ear,jar=server.jar,name=MySingletonClass,service=EJB3' **")

DEPLOYMENTS IN ERROR:
  Deployment "jboss.j2ee:ear=mmpl.ear,jar=server.jar,name=MySingletonClass,service=EJB3" is in error due to the following reason(s): ** NOT FOUND Depends on 'jboss.j2ee:ear=mmpl.ear,jar=server.jar,name=MySingletonClass,service=EJB3',whenRequired=MapControllerStateModel$ControllerStateWrapper@7ba014{Installed},dependentState=MapControllerStateModel$ControllerStateWrapper@7ba014{Installed} **, ** NOT FOUND Depends on 'jboss.j2ee:ear=mmpl.ear,jar=server.jar,name=MySingletonClass,service=EJB3' **
StormeHawke
  • 5,987
  • 5
  • 45
  • 73
  • It worked before, right? Does it work if you comment the usage of 'reader' bean (or the bean declaration itself)? – Piotr Nowicki Sep 19 '13 at 08:12
  • @PiotrNowicki Yes, messages are received if I comment out the `@EJB` line and its usage. Do I need to declare my singletons in an XML somewhere or something? – StormeHawke Sep 19 '13 at 14:36
  • No you don't need to declare them in XML. So there are no errors, even the first message is not arriving and no errors during deployment? One thing more - your Singleton EJB is implementing an interface. Do you have any annotations in this interface? Is it local business i-face (by default) or something else? In your MDB you're accessing Singleton using its actual class type instead of this interface, so you're trying to use no-interface view of the EJB. Do you declare it so (`@LocalBean`)? Can you try using its business interface instead? – Piotr Nowicki Sep 19 '13 at 14:52
  • @PiotrNowicki it only implements the `interface` to enforce some conventions between this and future, similar classes. There are no annotations on the `interface`. – StormeHawke Sep 19 '13 at 14:54
  • @PiotrNowicki also, if I use the `interface` in my MDB, how would it know which implementation of that `interface` to populate? Eventually there will be several – StormeHawke Sep 19 '13 at 14:55
  • @PiotrNowicki Added the interface – StormeHawke Sep 19 '13 at 15:58
  • If there are no annotations on the interface and your Singleton EJB is implementing it then by default it is a local business interface. If you don't have `@LocalBean` on the EJB than the local business interface is the only one that your EJB is exposing. I'm not sure why it even works in your case - I think app server should throw some exception because you're trying to use no-interface view (`@EJB` on the class itself - not the interface) but you don't declare your EJB is exposing this view. – Piotr Nowicki Sep 19 '13 at 16:00
  • If you have more than one implementation of a single interface you need to tell container what implementation to use (e.g. using `@EJB(beanName attribute). Are you sure it is a `@Singleton` annotation from EJB - not from CDI package? – Piotr Nowicki Sep 19 '13 at 16:01
  • @PiotrNowicki `@Singleton` annotation from EJB - not from CDI package?` Yes, `javax.ejb.Singleton`. I don't understand your other comment - could you create an answer with a demonstration of what you mean? – StormeHawke Sep 19 '13 at 16:25
  • @PiotrNowicki I added some additional information and edited the annotations in the code to reflect changes as I've poked around at this – StormeHawke Sep 19 '13 at 18:04
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/37683/discussion-between-piotr-nowicki-and-stormehawke) – Piotr Nowicki Sep 19 '13 at 20:02

1 Answers1

0

I ended up abandoning the ejb singleton idea and using the following, which works perfectly:

public class MySingletonClass implements SomeInterface
{
   private ScheduledFuture<?> handle;
   private static ScheduledExecutorService executor;
   private static SomeInterface instance;

   public void readResponseMsg(Document responseXml)
   {
       resetTimer();
       //do stuff
   }

   /**
    * Creates the timer.
    */
   private void resetTimer()
   {
      if (handle != null)
      {
         handle.cancel(false);
      }
      handle = executor.schedule(this, 30l, TimeUnit.SECONDS);
   }


   /**
    * Initialize the static variables. Should only be called once per server
    * restart
    */
   private static void init()
   {
      try
      {
         executor = Executors.newSingleThreadScheduledExecutor();
         inited = true;
      }
      catch (Exception e)
      {
         ourLogger.error("Exception initializing ScheduleResultReader", e);
      }
   }

   public static SomeInterface getInstance()
   {
      if (instance == null)
      {
         instance = new MySingletonClass();
      }

      return instance;
   }

}
StormeHawke
  • 5,987
  • 5
  • 45
  • 73