0

I have a ConfigParameter SLSB that reads configuration values from the ejb-jar.xml file.

This class has only private fields and for each field a corresponding getter method. In my application I have a lot of other EJBs that use an instance of ConfigParameter to read the configuration values.

Now, I thought it would be good idea to make ConfigParameter a @Singleton, since its state is shared across the whole application.

But in the ejb-jar.xml I can set session-type only to Stateful or Stateless. The file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0">
  <enterprise-beans>    
    <session>
      <ejb-name>ConfigParameter</ejb-name>
      <ejb-class>myapp.util.ConfigParameter</ejb-class>      
      <session-type>Stateless</session-type> <!-- make this a Singleton -->
      <env-entry>
        <env-entry-name>adminRoleName</env-entry-name>
        <env-entry-type>java.lang.String</env-entry-type>
        <env-entry-value>admin</env-entry-value>
      </env-entry>
    </session>
  </enterprise-beans>
</ejb-jar>

My questions are:

  1. Is it a good idea to make this bean a singleton?
  2. If yes, how can I achieve this?
  3. For understanding: Why is it not allowed to set session-type to Singleton?
hage
  • 5,966
  • 3
  • 32
  • 42
  • Is `ConfigParameter` a simple POJO that only contains primitive and/or String fields that are all retrieved from environment entries? – shelley Nov 18 '11 at 22:58
  • `COnfigParameter` was a POJO annotated with `@Stateless`. The field values were injected via `@Resource(name="...")`. I followed Piotr Nowickis answer and I have a Singleton now – hage Nov 19 '11 at 13:09

2 Answers2

3

You're using EJBs 3.0. Singleton EJBs were introduced in EJB 3.1. If you want to define it in ejb-jar.xml you should define appropriate version (note the version attribute and XSD location changed to 3.1)

<ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:ejb="http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" 
    version="3.1">

Or just use @Singleton annotation on the EJB class itself.

And yes - I would definitely say that it's appropriate to mark application-wide configuration bean as Singleton.

Piotr Nowicki
  • 17,914
  • 8
  • 63
  • 82
  • Thank you! I had my EJB annotated with `@Singleton`, but Eclipse didn't let me use Singleton as `session-type` because of the 3.0 specification. And having Stateless and Singleton definition caused the problem. Now it works. Great. – hage Nov 14 '11 at 09:21
  • @hage glad it worked! However, you know that you don't need to specify it in both - annotations and ejb-jar.xml (one of these place is sufficient), right? – Piotr Nowicki Nov 14 '11 at 09:27
  • I know - now :) Someone else in our team created both parts. We're all pretty new to the whole JavaEE and EJB stuff :) – hage Nov 14 '11 at 09:46
  • @hage yeah, these 'someone else did this, so I'll just do the same' are very common :-) In the project I work we had a LOT of `@AttributeOverride` annotations without any reason. Someone needed that in one place and the others just copy-pasted it without a grasp :-) Have fun in JavaEE world :-) – Piotr Nowicki Nov 14 '11 at 10:05
0

While the Singleton EJB is a good option, I'd like to propose another idea for consideration. Depending on how many values you need and where they are used, this may or may not be a better approach.

Since your ConfigParameter Singleton EJB is just a POJO that retrieves its values from JNDI via the @Resource annotation, it may be possible for you to use module or application-scoped environment entries (java:module, java:app) instead. This could eliminate the need for this extra EJB class; instead, you can just use the @Resource annotation within each of the EJBs that needs the values. To do this, just use the @Resource annotation within the EJB/web component that requires the value, using a name prefixed with either java:module or java:app: @Resource(name="java:app...").

Community
  • 1
  • 1
shelley
  • 7,206
  • 4
  • 36
  • 63