Discussions

News: Setting up a JNDI context using Spring

  1. Setting up a JNDI context using Spring (16 messages)

    James Strachan has a blog entry discussing how to use Spring to set up a JNDI context, in context of setting things up for ServiceMix.

    This is another advantage for Spring, given that configuring JNDI is typically very difficult to do across containers. Typically, configuring JNDI on application server startup is limited to certain types of elements supported by the specific application server, which works well for some data sources (queues, topics, datasources) and poorly for other types.

    Threaded Messages (16)

  2. The point.[ Go to top ]

    Who is going to load jndi.xml?

    The only benefit I see is being able to create InitialContext as bean and have ability to set it to beans extending JndiAccessor instead of using Properties.
  3. The point.[ Go to top ]

    Who is going to load jndi.xml?The only benefit I see is being able to create InitialContext as bean and have ability to set it to beans extending JndiAccessor instead of using Properties.

    The JNDI provider (InitialContextFactory) does the loading for you. When you create an InitialContext() it will automatically load the jndi.xml, using Spring, and expose all the objects it created as a JNDI context.

    As an end user, you just do context = new InitialContext() and it just works.

    I'm kinda surprised noone has done this before, but I guess most folks run stuff in Tomcat or a J2EE app server which have JNDI contexts available.

    If folks find this useful, I'm sure we could contribute it back into Spring for others to reuse.

    James
    LogicBlaze
  4. But we dont want to do "context = new InitialContext()" instead let the the BeanContext to pass the InitialContext to our object.

    Still its a nice trick for those who dont want to hardcode Context environment outside the container.
  5. But we dont want to do "context = new InitialContext()" instead let the the BeanContext to pass the InitialContext to our object.

    Sure, in that case you can embed or include the contents of jndi.xml inside your Spring.xml and just use the JNDI context as a regular bean in the usual Spring way - as its just a POJO.

    Or just add the following into whatever POJO you wanna pass a context...

    <property name="context">
      <bean class="javax.naming.InitialContext"/>
    </property>

    James
    LogicBlaze
  6. Do you still need to define jndi.properties?

    "All thats required is to define this jndi.properties on the classpath

    java.naming.factory.initial = org.servicemix.jbi.jndi.SpringInitialContextFactory"
  7. Do you still need to define jndi.properties?"All thats required is to define this jndi.properties on the classpathjava.naming.factory.initial = org.servicemix.jbi.jndi.SpringInitialContextFactory"

    If you want to use the regular JNDI bootstrap mechanism of creating a new InitialContext() yes. Or you can pass that property in as a parameter of the InitialContext if you prefer to avoid the jndi.properties on the classpath.

    Or if you are in a pure Spring environment you can just refer to the JNDI context POJO using a regular Spring bean reference and then there's no need for jndi.properties

    James
    LogicBlaze
  8. Cool thats what I needed.
  9. JNDI versus DBCP[ Go to top ]

    I think this is a related question, so i'll ask here.

    What is the benefit of using JNDI in a pure Spring environment (i mean where spring is injecting DAOs and handling transactions). Why should I set up JNDI in my appserver and in spring, instead of just using something like the Commons pooling defined in a Spring file? I know the latter way is more portable between app servers, but what benefits (while using Spring) do i get that should make me use jndi set up in the app server instead?

    hope that made sense..
  10. JNDI versus DBCP[ Go to top ]

    I think this is a related question, so i'll ask here.What is the benefit of using JNDI in a pure Spring environment (i mean where spring is injecting DAOs and handling transactions). Why should I set up JNDI in my appserver and in spring, instead of just using something like the Commons pooling defined in a Spring file? I know the latter way is more portable between app servers, but what benefits (while using Spring) do i get that should make me use jndi set up in the app server instead?hope that made sense..

    If you're in a pure Spring world I'd recommend ignoring JNDI completely as its just a PITA :)

    The only real requirement for using JNDI is if you have some component which depends on it already - such as some legacy J2EE stuff.

    In our case we're working on a Spring based ESB which the components deployed in it might depend on JNDI but we want to use Spring to configure our services and components where possible.

    James
    LogicBlaze
  11. JNDI versus DBCP[ Go to top ]

    cool..thx james
  12. Why JNDI?[ Go to top ]

    Jeff
    What is the benefit of using JNDI in a pure Spring environment (i mean where spring is injecting DAOs and handling transactions). Why should I set up JNDI in my appserver and in spring, instead of just using something like the Commons pooling defined in a Spring file?
    One of the great advantages of Spring is that you have choice. So there is no hard and fast answer here: it depends on your requirements. And the great thing is that you won't need to change your code in either case, and will need only to make trivial, localized, changes to XML.

    In general a local datasource will work just fine in any environment. The main reasons to use a container datasource are:
    1. If you need distributed transactions (in which case you also use the Spring JtaTransactionManager). In this case, if you're using a high-end app server, you should take advantage of its 2PC, recovery support etc.
    2. If you want to take advantage of monitoring tools provided by your application server, for example, to administer pools conveniently across a cluster, monitor inflight transactions etc.
    3. If you have multiple apps sharing the same datasource, and want a larger pool for all of them.

    Only (1) really dictates a container datasource, and that applies to a minority of applications. Of course the downside is greater complexity, and loss of the ability just to drop say a WAR on any server and have it completely self-contained.

    Generally I find that using a local datasource is great for prototyping. And of course the ability to use a local datasource in out-of-container integration testing, for example using the org.springframework.test superclasses, is a huge productivity boost.

    It's a best practice to break out the datasource and transaction manager into one XML fragment. You can then assemble your application context in a testing environment and deployed environment (if using JTA), using every other XML file unchanged, but with the appropriate datasource/tx mgr fragment.

    Rgds
    Rod
    Spring from the Source - Training, Consulting, Support
  13. SpringInitialContextFactory[ Go to top ]

    I surely miss something very obvious...
    But where can I found the "simple wrapper" org.servicemix.jbi.jndi.SpringInitialContextFactory ? I don't see it in the servicemix-1.0-M1.jar.
    Anyway, this kind of solution is exactly what I need at the time being.
    Thx,

    Bertrand
    Ippon Technologies
  14. You are the man, James. Nothing earth-shattering here, but I really like how you keep coming up with elegant ways to embed non-trivial infrastructural components into our apps while retaining the loosely coupled interfaces.
  15. You are the man, James. Nothing earth-shattering here, but I really like how you keep coming up with elegant ways to embed non-trivial infrastructural components into our apps while retaining the loosely coupled interfaces.

    Agreed, its nothing earth shattering - but thanks for your kind words.

    As Billy said in a blog post recently, there does seem to be a trend away from big J2EE application servers to using just the middleware/tools you need to get the job done. This is just a handly little trick to use Spring to configure JNDI contexts which you can then expose for other components to use.

    Its typically most useful when working with legacy/J2EE components which don't use dependency injection but instead insist on looking stuff up in JNDI - so its a handy bridge from the old world to the new :)

    James
    LogicBlaze
  16. On a recent project, we used spring-configured datasources pooled with commons dbcp. We didn't want to depend on the container at all for connection pooling, because we wanted the db-using tests to run independent of a container (and some Swing apps might not even run in a container. We also use multiple databases/ids for different environments (local, staging, prod, etc).

    We configured these with property files, using spring's property-override mechanism to load the correct db props (url/id/etc) from an environment-specific property file (either on the classpath for singleton environments like prod, or in user.home for local individual developer databases.

    However, the problem with this is that if you need to change a database's properties (for example, migrate to a different server/user/url), you have to manually edit these property files, which can be a pain and risky for multiple production apps on multiple servers which use the same database.

    I thought that a standalone JNDI server would be the perfect solution for this. You could store the config information in JNDI - one user/environment specific key for the url, and another for the id. The password would be handled separately, but that wouldn't necessarily have to change even if the database migrated.

    Would this be a good idea, or am I missing some more obvious and simple solution?

    -- Chad Woolley
  17. JNDI-Spring Example[ Go to top ]

    I've read the conversation here. Because I'm nearly new in this business, I don't know exactly how to integrate this solution. Can somebody help me or give some more information?
    I've just downloaded the Servicemix 2.0.2, so I suppose I have to integrate the .jar-files?
    I'm developping in eclipse and use JBoss as application / web server.
    I previously used the following command to call my xml-config file: ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("app-Servlet.xml");
    and than call the bean: ctx.getBean("dbco")
    I tried different solutions but couldn't get JNDI working with spring. What do I exactly need to change?