开发者

ejb3.1 @Startup.. @Singleton .. @PostConstruct read from XML the Objects

I need to initialize a set of static String values stored in an XML files [ I know this is against the EJB spec ] as shown below since the over all Idea is to not hardcore within EJB's the JNDI info

Utils.xml 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="jndidb">java:jdbc/MYSQLDB10</entry>
<entry key="jndimdbque">java:jms/QueueName/remote</entry>
<entry key="jndi1">DBConnections/remote</entry>
<entry key="jndi2">AddressBean/remote</entry>
</properties>

The Onload of ejbserver startup code is as follows ... inpstrem = clds.getClassLoaders(flename) Reads the Util.xml and stores the same in Hashtable key value pare....

package com.ejb.utils;

import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.Singleton;
import javax.ejb.Startup;

@Singleton
@Startup
public class StartupUtils  {

private final String INITFILENAME      = "/System/Config/Utils.xml";  
private static Hashtable HTINITFLENME=null,HTERRINITFLENME=null,HTCMMNFLENME=null;

public StartupUtils() {
    HTINITFLENME = new Hashtable();
    HTERRINITFLENME = new Hashtable();
}

public void printAll(Hashtable htcmmnflenme){
    Enumeration ENUMK = null, VALS = null;
    String KEY = "", VALUE = "";
    ENUMK = htcmmnflenme.keys();         
    while (ENUMK.hasMoreElements()) {
        KEY = null;VALUE = null;
        KEY = (ENUMK.nextElement().toString().trim());
        VALUE = htcmmnflenme.get(KEY).toString().trim();
        InitLogDisplay(KEY +  " :::: " + VALUE);
    }
}

public static  void InitLogDisplay(String Datadisplay){
   System.out.println(Datadisplay); 
}

public Hashtable getDataProp(String flename){
    Map htData = null;
    InputStream inpstrem = null;        
    ClassLoaders clds = null;
    Enumeration enumk = null, vals = null;
    String key = "", value = "";
    Properties props = null;
    Hashtable htx = null;       
    try {
        clds = new ClassLoaders();          
        inpstrem = clds.getClassLoaders(flename);           
        props = new Properties();
        props.loadFromXML(inpstrem);                    
        enumk = props.keys();
        vals = props.elements();
        htData = new HashMap();
        htData = new TreeMap();
        while (enumk.hasMoreElements()) {
              key = (enumk.nextElement().toString().trim());
          value = (vals.nextElement().toString().trim());
          htData.put(key,value);                
        }
        clds = null;
        props = null;
        inpstrem.close();
        } catch (Exception e) {
        e.printStackTrace();
        }finally{
         key = ""; value = "";
         enumk = null;vals = null;
         clds=null;
         props=null;
         }
        htx = new Hashtable();
        htx.putAll(htData);
        return htx;
    }


    public void setUtilsPropDetails(){
        HTINITFLENME = getDataProp(INITFILENAME);
        this.printAll(HTINITFLENME);
    }

    public static Hashtable getUtilsPropDetails(){
        return HTINITFLENME;
    }

    @PostConstruct  
    public void startOnstartup(){       
      this.setUtilsPropDetails();
          this.printAll();          
    }

    @PreDestroy
    public void startOnshutdown(){      
        try {
            this.finalize();
        } catch (Throwable e) {
           e.printStackTrace();
        }       
    }   
}

On startup of EJB server "this.printAll(HTINITFLENME);" prints the key values of the XML file hoever If an external Call is made via any other EJB's to the method "getUtilsPropDetails()" 开发者_Python百科does not return the key values....

Am i doing something wrong ??????


Have you considered using the deployment descriptor and having the container do this work for you?

There are of course <resource-ref>, <resource-env-ref>, <ejb-ref> and <env-entry> elements to cover externally configuring which things should be made available to the bean for lookup. For example:

<resource-ref>
    <res-ref-name>db</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <mapped-name>java:jdbc/MYSQLDB10</mapped-name>
</resource-ref>

I'm not sure how your vendor handles mapped-name (that particular element is vendor specific), but there will be an equivalent syntax to specify the datasource you want.

The singleton can then lookup java:comp/env/db and return the datasource to other EJBs.

If you are in a compliant Java EE 6 server, then you can change the name to <res-ref-name>java:app/db</res-ref-name> and then anyone in the app can lookup the datasource without the need to get it from the singleton. Global JNDI is a standard feature of Java EE 6 and designed for exactly this.

You can put those elements in the ejb-jar.xml, web.xml or application.xml. Putting them in the application.xml will make the one entry available to the entire application and give you one place to maintain everything.

Global resources can also be injected via:

@Resource(name="java:app/db")
DataSource dataSource;

If for some reason you didn't want to use those, at the very least you could use the <env-entry> element to externalize the strings.

EDIT

See this other answer for a much more complete description of JNDI as it pertains to simple types. This of course can be done where the name/value pairs are not simple types and instead are more complex types like DataSource and Topic or Queue

For example:

  <resource-ref>
    <res-ref-name>myDataSource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
  </resource-ref>
  <resource-ref>
    <res-ref-name>myJmsConnectionFactory</res-ref-name>
    <res-type>javax.jms.ConnectionFactory</res-type>
  </resource-ref>
  <resource-ref>
    <res-ref-name>myQueueCF</res-ref-name>
    <res-type>javax.jms.QueueConnectionFactory</res-type>
  </resource-ref>
  <resource-ref>
    <res-ref-name>myTopicCF</res-ref-name>
    <res-type>javax.jms.TopicConnectionFactory</res-type>
  </resource-ref>
  <resource-env-ref>
    <resource-env-ref-name>myQueue</resource-env-ref-name>
    <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
  </resource-env-ref>
  <resource-env-ref>
    <resource-env-ref-name>myTopic</resource-env-ref-name>
    <resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
  </resource-env-ref>
  <persistence-context-ref>
    <persistence-context-ref-name>myEntityManager</persistence-context-ref-name>
    <persistence-unit-name>test-unit</persistence-unit-name>
  </persistence-context-ref>
  <persistence-unit-ref>
    <persistence-unit-ref-name>myEntityManagerFactory</persistence-unit-ref-name>
    <persistence-unit-name>test-unit</persistence-unit-name>
  </persistence-unit-ref>

See the JNDI and simple types answer for look and injection syntax.

I see the name and type, but where's the value?

Configuring what actual things these names refer to has historically been done in a separate vendor specific deployment descriptor, such as sun-ejb-jar.xml or openejb-jar.xml or whatever that vendor requires. The vendor-specific descriptor and the standard ejb-jar.xml descriptor combined provide the guaranteed portability apps require.

The ejb-jar.xml file offering only standard things like being able to say what types of resources the application requires and what names the application has chosen to use to refer to those resources. The vendor-specific descriptor fills the gap of mapping those names to actual resources in the system.

As of EJB 3.0/Java EE 5, we on the spec groups departed from that slightly and added the <mapped-name> element which can be used in the ejb-jar.xml with any of the references shown above, such as <resource-ref>, to the vendor-specific name. Mapped name will never be portable and its value will always be vendor-specific -- if it is supported at all.

That said, <mapped-name> can be convenient in avoiding the need for a separate vendor-specific file and achieves the goal of getting vendors-specific names out of code. After all, the ejb-jar.xml can be edited when moving from one vendor to another and for many people that's good enough.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜