Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Virgo » [SOLVED] Using the embedded Tomcat for JNDI and DataSources(A possible approach to using Tomcat support for JDBC datasources and few related questions)
[SOLVED] Using the embedded Tomcat for JNDI and DataSources [message #932556] Thu, 04 October 2012 08:03 Go to next message
GianMaria Romanato is currently offline GianMaria RomanatoFriend
Messages: 72
Registered: July 2009
Member
I have an OSGi enterprise application made of multiple persistence units, each of them in its own bundle. The units correspond to multiple functional components, but I need all of them to be persisted in the same database instance.

When you have multiple persistence units, each of them in its own bundle and with its own persistence.xml file, you define connection parameters in every persistence.xml file. If I use the JDBC driver manager and leverage the persistence provider pooling, each different persistence unit will have its own pool, which is not optimal when the database is only one.

The best approach would be to define a single datasource, declare it in all persistence.xml, thus letting all units share the same pool.

I am using EclipseLink as the persistence provider. I tried using Gemini-JPA to obtain connections from a DataSource; unluckily it turns out that there is an issue in the Gemini-JPA/EclipseLink integration, https://bugs.eclipse.org/bugs/show_bug.cgi?id=379397, and pooling is not available, which makes this solution not usable in production.

Virgo 3.5 itself does not offer a simple facility to define datasources, and at the same time to be fully OSGi Enterprise compliant one should make use of Gemini Naming. But, if I am not mistaken, when using Gemini Naming, the only way to bind a datasource in the naming directory, consists in writing a bundle activator that programmatically instantiates the Data Source and registers it in the naming directory, in which case it is also my duty to implement the pool, and I would need to deal with an external configuration file to let system administrators change the database connection, pool size etc when appropriate.

So here is the idea: Tomcat itself is capable of managing JDBC DataSources and altought there is no graphical UI to define them, editing tomcat-server.xml is not that complex, the feature is there and is documented. So a colleague of mine spent a couple of days trying to figure out how we could leverage Tomcat to manage pooled datasources.

And here is the solution my colleague Stefano found:

  1. extend the catalina bundle with a fragment that contains dbcp, which is not included in Virgo ootb
  2. extend the catalina bundle with a fragment that contains the database driver
  3. create a "JNDI" bundle to be started as the very first bundle, which obtains the global naming context from catalina via JMX API, and then registers in the JVM a InitialContextFactoryBuilder using NamingManager.setInitialContextFactoryBuilder()



In this way any subsequent use of "new InitialContext()" will create a context that delegates to the global naming context obtained from Catalina. It is thus possible to write in the code "new InitialContext()" as if it was a J2EE application and lookup resources declared in Tomcat's tomcat-server.xml
The resulting code has the advantage of being portable to J2EE, and it is also friendly towards legacy libraries not written to lookup resources in the OSGi enterprise way. I am also quite confident that if you used WebSphere as an OSGi container, WebSphere would allow to use JNDI in the same way, so I believe the application should be portable across different OSGi containers.

We had a look at GeminiNaming source code and found out that GeminiNaming is setting the InitialContextFactoryBuilder as well, so we believe that the operation is allowed by Virgo (and in fact everything is working properly).

Now, my main questions are:

  1. do you think this is a legit approach?
  2. why not offer this feature ootb in Virgo for Tomcat?
  3. why not ship dbcp with Virgo for Tomcat?


An alternative approach to be tested may consist in writing a Tomcat-GeniniNaming bridge that looks up resources in Tomcat tomcat-server.xml and binds them in GeminiNaming directory context.


GianMaria


Developing for Virgo using PDE: http://bit.ly/1w0tTit
Global JNDI in Virgo: http://bit.ly/1to42mn
Hyperic to monitor Virgo: http://bit.ly/W1Fst9
Profile Virgo with JProfiler http://bit.ly/1FBLGCw

[Updated on: Wed, 31 October 2012 08:11]

Report message to a moderator

Re: Using the embedded Tomcat for JNDI and DataSources [message #933017 is a reply to message #932556] Thu, 04 October 2012 16:52 Go to previous messageGo to next message
Violeta Georgieva is currently offline Violeta GeorgievaFriend
Messages: 278
Registered: October 2010
Senior Member
Hi,

Quote:
And here is the solution my colleague Stefano found:

extend the catalina bundle with a fragment that contains dbcp, which is not included in Virgo ootb


that's correct

Quote:

extend the catalina bundle with a fragment that contains the database driver


that's correct

Quote:

create a "JNDI" bundle to be started as the very first bundle, which obtains the global naming context from catalina via JMX API, and then registers in the JVM a InitialContextFactoryBuilder using NamingManager.setInitialContextFactoryBuilder()


I didn't get this. Why do you need to do this? There is a so called "Resource Link" provided by the Tomcat with which you can lookup a global resource. http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Resource%20Links

Quote:

An alternative approach to be tested may consist in writing a Tomcat-GeniniNaming bridge that looks up resources in Tomcat tomcat-server.xml and binds them in GeminiNaming directory context.


There is already such "bridge". Virgo Server for Apache Tomcat uses Gemini Web that embeds Tomcat.
Gemini Web provides this functionality - see the user documentation - http://eclipse.org/gemini/web/documentation/gemini-web-documentation-2.1.0.RELEASE/gemini-web-user-guide/htmlsingle/gemini-web-user-guide.html#configuring-tomcat - chapter "JNDI Resources"


I can prepare an example if you think it will be helpful?

Regards
Violeta
Re: Using the embedded Tomcat for JNDI and DataSources [message #933755 is a reply to message #933017] Fri, 05 October 2012 10:09 Go to previous messageGo to next message
GianMaria Romanato is currently offline GianMaria RomanatoFriend
Messages: 72
Registered: July 2009
Member
Ciao Violeta,

first of all thank you very much for your answers. Please see my comments below.

Quote:

Quote:
extend the catalina bundle with a fragment that contains dbcp, which is not included in Virgo ootb

that's correct


If this is the right approach, why not bundle dbcp and tomcat-jdbc pool implementations with Virgo? Or at least why not declare an optional dependency toward those Java packages, so that we only need drop the bundles in the repository and fragments are no more necessary ? (besides of course the JDBC driver fragment that will always be necessary)
Do you want me to file an issue to bugzilla with severity ENHANCEMENT for possible resolution in Virgo 3.6?

I understand that in alternative to JDBC driver fragments it is possible to put the driver inside the Web App, but I don't like this approach that much, because it would require me to repackage the Web App when the target database changes or, even worse, when an updated driver is made available.

Quote:

I didn't get this. Why do you need to do this? There is a so called "Resource Link" provided by the Tomcat with which you can lookup a global resource. http://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Resource%20Links


The problem is that not all threads that need work with the database in our application originate from the Web container.

My colleague Stefano verified that if you use the "resource-link", the JNDI lookup will succeed if and only if it is performed within a thread that is originated by Tomcat to serve an HTTP request.
In fact, the need to declare a <ResourceLink> otherwise the Web App won't be able to get the resource, implies that you cannot get the JNDI resources from bundles that are not Web Apps (or better WABs), unless the code is being executed in a Web thread.

If you are developing a Web Application for Tomcat all threads will be those created by Tomcat. In J2ee for example this is not true as your code may be executed when a JMS message is published to a bus.

Even without JMS, our application need use the database in threads not originated by the Web container, for example:


  • we use a scheduler (Quartz) to perform a number of asynchronous operations that are triggered for certain Web requests and the threads used by the scheduler to execute our jobs won't be able to get the data source.
  • our application takes advantage of the OSGi bundle lifecycle events to support hot-swapping of components. It implements several BundleListeners and make use of the OSGi Extender pattern to deal with the installation/removal of additional OSGi bundles representing functional components. Whenever a bundle is installed/uninstalled the listeners are executed by threads that are created by Equinox and some of the listeners need use the database but in those threads the JNDI lookup would fail.


The GeminiWeb bridge you are mentioning is not a good fit for us, because JNDI visibility remains limited to the Web App.

Maybe GeminiNaming could be a solution, but it is not included OOTB in Virgo, and we couldn't figure out how to use it with Tomcat resources. Plus, it seems to require that resource binding is done programmatically, which is not good for us because we need JDBC Datasources to be configured easily and quickly by system administrators that don't have OSGi programming skills.

To be able to use JDBC Datasources freely, in any thread, regardless of how that thread got instantiated and executed, we need the JNDI resources to be globally available, and as such we implemented a "JNDI" bundle that starts as the very first, obtains resources from Tomcat and registers an InitialContextFactoryBuilder as I tried to explain in my previous post.

Are there alternative approaches that satisfy our requirements?

Thanks
GianMaria






Developing for Virgo using PDE: http://bit.ly/1w0tTit
Global JNDI in Virgo: http://bit.ly/1to42mn
Hyperic to monitor Virgo: http://bit.ly/W1Fst9
Profile Virgo with JProfiler http://bit.ly/1FBLGCw
Re: Using the embedded Tomcat for JNDI and DataSources [message #938176 is a reply to message #933755] Tue, 09 October 2012 16:20 Go to previous messageGo to next message
Thomas Kölling is currently offline Thomas KöllingFriend
Messages: 45
Registered: December 2011
Location: Munich
Member
Hi,

I'm interested in a thread independent solution too. You can see a similar behavior, when you try to obtain a jndi datasource from the spring (gemini blueprint) extender thread (which creates your spring context) on an equinox runtime embedded in a servlet. From a native osgi bundle the jndi context is accessible, from the spring context not. But now i'm trying to obtain the datasource from virgo for tomcat with gemini naming. A step by step guide for this would be nice.

greetings,
thomas
Re: Using the embedded Tomcat for JNDI and DataSources [message #939066 is a reply to message #938176] Wed, 10 October 2012 11:50 Go to previous messageGo to next message
GianMaria Romanato is currently offline GianMaria RomanatoFriend
Messages: 72
Registered: July 2009
Member
Ciao Thomas,

let's wait a couple more days waiting for Violeta, who is a Virgo committer, to give us her advice, then I'll provide you more details.

GianMaria.


Developing for Virgo using PDE: http://bit.ly/1w0tTit
Global JNDI in Virgo: http://bit.ly/1to42mn
Hyperic to monitor Virgo: http://bit.ly/W1Fst9
Profile Virgo with JProfiler http://bit.ly/1FBLGCw
Re: Using the embedded Tomcat for JNDI and DataSources [message #940589 is a reply to message #939066] Thu, 11 October 2012 19:49 Go to previous messageGo to next message
Violeta Georgieva is currently offline Violeta GeorgievaFriend
Messages: 278
Registered: October 2010
Senior Member
Hi,

While reading your requirements, it came to my mind - did you try using Gemini DBAccess (http://eclipse.org/gemini/dbaccess/). It might fit here very well.
Here you can find also examples (http://wiki.eclipse.org/Virgo/Samples - Virgo & Gemini Tutorial).
Once exposing the DataSourceFactory service in the OSGi registry you can consume it from every bundle, normal and web bundle.

If not then we can think of another approach.

Regards
Violeta
Re: Using the embedded Tomcat for JNDI and DataSources [message #941216 is a reply to message #940589] Fri, 12 October 2012 09:57 Go to previous messageGo to next message
GianMaria Romanato is currently offline GianMaria RomanatoFriend
Messages: 72
Registered: July 2009
Member
Ciao Violeta,

fist of all thank you very much for taking the time to reply to my questions.

Quote:

While reading your requirements, it came to my mind - did you try using Gemini DBAccess (http://eclipse.org/gemini/dbaccess/). It might fit here very well.


Yes I tried DBAccess in the past but eventually dropped it because:


  1. Gemini DBAccess is available only for Derby, and to use a different database I would need to write my own implementation. Not a big issue but some extra effort anyway
  2. To use it with EclipseLink I should probably use it via GeminiJPA, which is affected by a bug that prevents connection pooling from working and is therefore not usable in production https://bugs.eclipse.org/bugs/show_bug.cgi?id=379397
  3. To use DBAccess with GeminiJPA I would need to configure connection parameters in each bundle's persistence.xml which is inconvenient because I would need to repackage the bundles if the connection parameters change, and due to the modular nature of my application I have several bundles containing persistence units.
  4. If I decide to use DBAccess witout GeminiJPA, DBAccess will provide me with a data source factory, then it will me my duty to instantiate and configure it. And in such case I would need to support a configuration file to let system administrators easily change connnection parameters, which is again extra effort.
  5. As the name implies, Gemini DBAccess is tailored to data base resources, while I would like a single approach for looking up any type of resource, possibly in a unified way. Here Tomcat is a better option because it supports several resource types and could also be extended to support additional resources http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#Adding_Custom_Resource_Factories
  6. Finally, correct me if I am wrong, but DBAccess requires the OSGi registry, which means it would not work with legacy code or third party libraries written for J2EE, unless I write my own InitialContextFactoryBuilder and register it in the JVM NamingManager, as I explained in my previous posts, which means the approach would be the same as in my first post, with the drawback of supporting only data source resources.


Quote:

Here you can find also examples (http://wiki.eclipse.org/Virgo/Samples - Virgo & Gemini Tutorial).


Thank you for the URL, I did not know those samples existed.

I don't want to waste too much of your time, I just would like to understand if you believe that my approach is legit or if to the contrary you believe it's risky/broken or maybe soon to be invalidated by an upcoming release of Virgo.
Overall I am pretty happy with it, it's been tested and working perfectly, but I would like to understand if a person like you who knows the internals of Virgo considers it a viable solution or to the contrary a very bad and weak hack.

If you confirm it's a legit approach, I'll write a detailed post to document it for others.

Thank you
GianMaria


Developing for Virgo using PDE: http://bit.ly/1w0tTit
Global JNDI in Virgo: http://bit.ly/1to42mn
Hyperic to monitor Virgo: http://bit.ly/W1Fst9
Profile Virgo with JProfiler http://bit.ly/1FBLGCw
Re: Using the embedded Tomcat for JNDI and DataSources [message #949751 is a reply to message #941216] Fri, 19 October 2012 08:52 Go to previous messageGo to next message
GianMaria Romanato is currently offline GianMaria RomanatoFriend
Messages: 72
Registered: July 2009
Member
Bumping the thread because a week has passed since my last post.

GianMaria.


Developing for Virgo using PDE: http://bit.ly/1w0tTit
Global JNDI in Virgo: http://bit.ly/1to42mn
Hyperic to monitor Virgo: http://bit.ly/W1Fst9
Profile Virgo with JProfiler http://bit.ly/1FBLGCw
Re: Using the embedded Tomcat for JNDI and DataSources [message #954975 is a reply to message #932556] Tue, 23 October 2012 12:00 Go to previous messageGo to next message
Thomas Kölling is currently offline Thomas KöllingFriend
Messages: 45
Registered: December 2011
Location: Munich
Member
Hi GianMaria,

Currently we use the DBAccess approach. I've written a data-source factory against the osgi enterprise spec (like gemini dbaccess) for an Oracle Driver (which is wrapped with the maven-bundle-plugin). To provide one or more datasources from the same or different data factories, i've written a datasource provider, which is configurable via the Configuration Admin & Spring Property Placeholder - which is a relative small afford. After that the DataSource can consumed by the persistent unit, in our case we use mybatis - so no JPA needed, and no JNDI.
Related to JNDI, i didn't see a reason to configure JNDI stuff and driver in the embedded web container, cause other bundles would use this source too, that means they are depend on the tomcat bundle (indirectly cause this configure the jndi resources). I think a better approach is, to use gemini naming - combined with the OSGi Enteprise JDBC Spec (Gemini DBAccess). Write a Configurable DataSource Provider - which register the DataSource in the JNDI Context via Gemini Naming - now your datasource should avaible in other bunldes - without tomcat dependency.

greetings thomas
Re: Using the embedded Tomcat for JNDI and DataSources [message #965419 is a reply to message #954975] Wed, 31 October 2012 08:09 Go to previous messageGo to next message
GianMaria Romanato is currently offline GianMaria RomanatoFriend
Messages: 72
Registered: July 2009
Member
Hi Thomas,

sorry for the late reply, thank you for your suggestion, but for a number of reasons that I already wrote in this thread it is not a good fit for me.

Today I posted to my personal blog a very detailed message that explains how to expose the global Tomcat JNDI registry to a OSGi application in Virgo, so that the code can lookup any type of resource regardless of the thread and the thread context class loader in use.

Here is the link, in case you may still be interested: http://devshards.blogspot.it/2012/10/global-jndi-support-in-virgo-server-35.html

GianMaria.


Developing for Virgo using PDE: http://bit.ly/1w0tTit
Global JNDI in Virgo: http://bit.ly/1to42mn
Hyperic to monitor Virgo: http://bit.ly/W1Fst9
Profile Virgo with JProfiler http://bit.ly/1FBLGCw
Re: Using the embedded Tomcat for JNDI and DataSources [message #985644 is a reply to message #965419] Thu, 15 November 2012 15:17 Go to previous message
Thomas Kölling is currently offline Thomas KöllingFriend
Messages: 45
Registered: December 2011
Location: Munich
Member
Nice approach!

I have a more generic question to this topic. Is the JNDI Context from tomcat a suitable way to share OSGi Services accross WAR files on the same Tomcat? I have a possible scenario where we have a backend war file with osgi embedded, which gain access to the tomcat jndi context - and a "client" war file, where something like GWT lives in, and consumes the backend services via jndi lookups...

is something similar possible? is there a problem with the different threads, which comes per request?

[Updated on: Thu, 15 November 2012 15:17]

Report message to a moderator

Previous Topic:How to deploy maven web project to Virgo?
Next Topic:Virgo tooling : Bundle dependencies broken once changed MANIFEST.MF of a installed bundle
Goto Forum:
  


Current Time: Wed Apr 24 20:23:52 GMT 2024

Powered by FUDForum. Page generated in 0.04634 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top