Best practice to add custom configuration to an EJB3 session bean?

  4 posts   Feedicon  
Replies: 3 - Last Post: October 23, 2010 08:03
by: abien
showing 1 - 4 of 4
 
Posted: October 20, 2010 15:20 by viggonavarsete
Hi,

I have a new Java EE 6 project which I have ported from a typical Spring project where all dependencies are wired up in XML files using beans. Some of the classes wired in Spring have configuration I would like to make customizable in my new project, like String pointing to URL's, port numbers etc. What would be the best way to achive this in Java EE 6? And how would I change the values in a runtime environment like JBoss 6?

The following example shows what I want to achive, but how can I change these values after deployment? http://javaevangelist.blogspot.com/2008/08/how-to-implement-ejb-30-in-ejb-jarxml.html

Best regards,
Viggo
 
Posted: October 22, 2010 19:38 by abien
Hi Viggo,

you could:

1. Inject fields the configuration using CDI
2. Use an Interceptor to set the fields via reflection (you could inject into this service)
3. Inject a configuration service (another CDI bean)
4. Use ejb-jar.xml (I would not use that)

(is a good candidate for a sub-chapter Smile),

thanks!,

adam
 
Posted: October 22, 2010 20:09 by viggonavarsete
Thanks for feedback Adam!

We've solved it this way:

public interface Config {
String getStringValue( String key );
}

@Stateless
public class PropertiesConfigBean implements Config {

Properties props = new Properties();

@PostConstruct
public void postConstruct() throws IOException {
setPropertiesFile( "config.properties" );
}

public String getStringValue( String key ) {
String val = (String) props.get( key );
if( val == null || "".equals( val ) ) {
throw new RuntimeException( "Attempt to read non-existing key " + key + " from config" );
}
return val;
}

private void setPropertiesFile( String filename ) throws IOException {
InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream( filename );
if( is == null ) {
throw new IOException( "File " + filename + " not found" );
}
props.load( is );
}

}

Any improvements/suggestions to improve our solution? We could also later create another implementation that read from a database instead of a Properties file. The config.properties is placed in src/main/resources and a test config file is placed in src/test/resources and picked up correctly during test.

The way it's implemented now we have no caching, but as a consequence the config is always refreshed each time it's readSmile Any input to caching strategy? Could it be implemented as a Singleton instead?
 
Posted: October 23, 2010 08:03 by abien
Fast review:

- it could be actually BeanManagedConcurrency Singleton (if you like to cache)
- an interceptor could use reflection to scan target bean for private fields and ask you bean for configuration. In case the configuration is available, it would set it, if not, the default from the bean would be used (it would be consistent with Convention over Configuration)
- You could use a CDI bean instead of EJB 3.1. Than you could use qualifiers to choose the configuration source (if needed it).

If you like, check it in. I could provide you push rights.

Small improvement -> I would not expose IOExceptions and throw e.g. IllegalStateExceptions instead.

Enjoy Java EE 6 hacking!.
Replies: 3 - Last Post: October 23, 2010 08:03
by: abien
  • Mysql
  • Glassfish
  • Jruby
  • Rails
  • Nblogo
Terms of Use; Privacy Policy;
© 2010, Oracle Corporation and/or its affiliates
(revision 20120518.3c65429)
 
 
Close
loading
Please Confirm
Close