Re: Database configuration on web application startup

2009-05-25 Thread Luis Fernando Planella Gonzalez
Yes, that should solve my problem.
In this case, the application name would be the servlet context path?
Another question: when the application is deployed in the server root url, 
which would be the app name? ROOT?
Anyway, since this seems a small addition to an already existing heuristic, and 
is generally useful (not only for my case), I've registered an issue at 
https://issues.apache.org/jira/browse/OPENEJB-1027

Luis Fernando Planella Gonzalez
lfpg@gmail.com
http://freeit.inf.br


Em Sexta-feira 22 Maio 2009, às 18:09:09, David Blevins escreveu:
> 
> On May 22, 2009, at 11:13 AM, Luis Fernando Planella Gonzalez wrote:
> 
> > * Several instances of the same application may be deployed in the  
> > same server. So, even that the user could create a data source in  
> > tomcat/conf/openejb.xml, he would have to change each application  
> > instance's META-INF/persistence.xml, which is packed inside a jar,  
> > inside another war. So, this is the showstopper. If weren't for  
> > this, it wouldn't be that bad to make the user set the data source  
> > in the tomcat file.
> 
> Still reading the email, but just wanted to post some initial thoughts  
> on this point.  We already don't require you to explicitly set the  
> data source names in the persistence.xml and will fill them in  
> automatically in some situations.  Our current "guessing" algorithm  
> wouldn't help you, but we might be able to beef it up to allow for  
> more kinds of matching.   Recently Karsten had a very similar  
> situation involving multiple persistence units and datasources to  
> match each:
> 
>
> http://www.nabble.com/Using-Multiple-PersistenceUnits-tp23520311p23534955.html
> 
> I suggest there that we might be able to improve the datasource  
> matching we do for persistence.xml files to look for data sources that  
> use the persistence unit name when looking for them by the name listed  
> fails.  That won't work for you as you have the same application  
> deployed several times and would need different datasources for each.  
> So as another fallback strategy we could maybe match my application  
> name.
> 
> The algorithm for resolving the datasources for a persistence unit  
> would then look like this:
> 
>Look for a datasource whose name matches:
>1. the name set in  or 
>2. the name of the persistence-unit
>3. the name of the module name (i.e. war, ejb-jar, etc.)
>4. the name of the app name (i.e. ear)
> 
> Then you could simply leave the   source> blank and configure a datasource for each application in your  
> openejb.xml file.
> 
> Would something like that work for you?  Seems like it would be a good  
> first step towards what you ultimately want and also a good solution  
> for Karsten.
> 
> -David
> 
> 


Re: Database configuration on web application startup

2009-05-23 Thread Jacek Laskowski
On Sat, May 23, 2009 at 1:16 AM, David Blevins  wrote:

>> I'd rather avoid introducing any
>> container-specific solutions unless they're really necessary. I think
>> the closer we are to other ejb containers (likely application servers
>> themselves) the better so people won't run into any issues during
>> their production deployments. How is it handled by other app servers?
>> GlassFish has a default datasource notion. What about JBAS or JOnAS or
>> WLS?
>
> Right, as you point out the spec says "the format of these names and the
> ability to specify the names are product specific" which makes it
> unavoidably container specific.  As far as I can see everyone has taken
> their own approach (Geronimo uses the AbstractName of the db pool gbean,
> JBoss uses the Jboss-specific jndi name of the datasource, etc. etc).  Not
> sure what we can do about that other than do our best to support the
> situations people bring to us.

I think it encourages us to use the Strategy design pattern with
GeronimoDataSourceFormat, JBossDataSourceFormat and such, so they
could be on/off to get as close to the production container as
possible. Ideas? Hints?

Jacek

-- 
Jacek Laskowski
Notatnik Projektanta Java EE - http://www.JacekLaskowski.pl


Re: Database configuration on web application startup

2009-05-22 Thread David Blevins


On May 22, 2009, at 2:45 PM, Jacek Laskowski wrote:


Really interesting.


Interesting indeed.  Like global ejb names, but worse.


I'd rather avoid introducing any
container-specific solutions unless they're really necessary. I think
the closer we are to other ejb containers (likely application servers
themselves) the better so people won't run into any issues during
their production deployments. How is it handled by other app servers?
GlassFish has a default datasource notion. What about JBAS or JOnAS or
WLS?


Right, as you point out the spec says "the format of these names and  
the ability to specify the names are product specific" which makes it  
unavoidably container specific.  As far as I can see everyone has  
taken their own approach (Geronimo uses the AbstractName of the db  
pool gbean, JBoss uses the Jboss-specific jndi name of the datasource,  
etc. etc).  Not sure what we can do about that other than do our best  
to support the situations people bring to us.


-David



Re: Database configuration on web application startup

2009-05-22 Thread Jacek Laskowski
On Fri, May 22, 2009 at 11:09 PM, David Blevins  wrote:

> Then you could simply leave the  
> blank and configure a datasource for each application in your openejb.xml
> file.

Interesting. I thought that leaving these elements blank would violate
the spec (I thought they're required) but I've just checked in the
spec and it turned out I was mistaken:

6.2.1.5 jta-data-source, non-jta-data-source
In Java EE environments, the jta-data-source and non-jta-data-source
elements are used
to specify the global JNDI name of the JTA and/or non-JTA data source
to be used by the persistence
provider. If neither is specified, the deployer must specify a JTA
data source at deployment or a JTA
data source must be provided by the container, and a JTA
EntityManagerFactory will be created to correspond
to it.
These elements name the data source in the local environment; the
format of these names and the ability
to specify the names are product specific.

Really interesting. I'd rather avoid introducing any
container-specific solutions unless they're really necessary. I think
the closer we are to other ejb containers (likely application servers
themselves) the better so people won't run into any issues during
their production deployments. How is it handled by other app servers?
GlassFish has a default datasource notion. What about JBAS or JOnAS or
WLS?

Jacek

-- 
Jacek Laskowski
Notatnik Projektanta Java EE - http://www.JacekLaskowski.pl


Re: Database configuration on web application startup

2009-05-22 Thread David Blevins


On May 22, 2009, at 11:13 AM, Luis Fernando Planella Gonzalez wrote:

* Several instances of the same application may be deployed in the  
same server. So, even that the user could create a data source in  
tomcat/conf/openejb.xml, he would have to change each application  
instance's META-INF/persistence.xml, which is packed inside a jar,  
inside another war. So, this is the showstopper. If weren't for  
this, it wouldn't be that bad to make the user set the data source  
in the tomcat file.


Still reading the email, but just wanted to post some initial thoughts  
on this point.  We already don't require you to explicitly set the  
data source names in the persistence.xml and will fill them in  
automatically in some situations.  Our current "guessing" algorithm  
wouldn't help you, but we might be able to beef it up to allow for  
more kinds of matching.   Recently Karsten had a very similar  
situation involving multiple persistence units and datasources to  
match each:


  http://www.nabble.com/Using-Multiple-PersistenceUnits-tp23520311p23534955.html

I suggest there that we might be able to improve the datasource  
matching we do for persistence.xml files to look for data sources that  
use the persistence unit name when looking for them by the name listed  
fails.  That won't work for you as you have the same application  
deployed several times and would need different datasources for each.  
So as another fallback strategy we could maybe match my application  
name.


The algorithm for resolving the datasources for a persistence unit  
would then look like this:


  Look for a datasource whose name matches:
  1. the name set in  or 
  2. the name of the persistence-unit
  3. the name of the module name (i.e. war, ejb-jar, etc.)
  4. the name of the app name (i.e. ear)

Then you could simply leave the  source> blank and configure a datasource for each application in your  
openejb.xml file.


Would something like that work for you?  Seems like it would be a good  
first step towards what you ultimately want and also a good solution  
for Karsten.


-David



Database configuration on web application startup

2009-05-22 Thread Luis Fernando Planella Gonzalez
Hi. First of all, sorry for the long post.
Some time has past since my last thread about programmatic database deployment 
on the web application startup.
First of all, the application is Cyclos (http://project.cyclos.org), which have 
the following requirements:
* The application is being rewritten in GWT / EJB3 (previously was Struts / 
Hibernate).
* It's an open source web application which may be downloaded and installed. 
* Users are used to having a single .properties to customize the database 
access. If possible, I'd like to keep the connection in a .properties inside 
the application.
* Several instances of the same application may be deployed in the same server. 
So, even that the user could create a data source in tomcat/conf/openejb.xml, 
he would have to change each application instance's META-INF/persistence.xml, 
which is packed inside a jar, inside another war. So, this is the showstopper. 
If weren't for this, it wouldn't be that bad to make the user set the data 
source in the tomcat file.

My goal: having each deployed application instance to have an automatically 
assigned data source, so that the user don't have to unpack the war, jar, 
modify the META-INF/persistence.xml and then repack.
Ideally, if it were possible use a variable in persistence.xml (something like 
${webApplicationContext}...),
 it would be perfect. Perhaps, it wouldn't be hard to implement this in OpenEJB 
(probably in TomcatWebAppBuilder).

So, to make things work, I started to research, and here is the solution I 
found (and really not satisfied with it, since it's an ugly hack, and not 
comfortable to put it in production):
* I created a custom class for the Tomcat Context handle, setting 
META-INF/context.xml with 
* I had to create a custom org.apache.openejb.config.DynamicDeployer which 
would wrap the existing deployer and do something else. However, since 
TomcatWebAppBuilder uses a ConfigurationFactory (but don't have a public 
getter), and ConfigurationFactory doesn't allow a custom deployer, I had to set 
a few private attributes through reflection:
WebAppBuilder webAppBuilder = 
systemInstance.getComponent(WebAppBuilder.class);
try {
Field configurationFactoryField = 
webAppBuilder.getClass().getDeclaredField("configurationFactory");
configurationFactoryField.setAccessible(true);
ConfigurationFactory configurationFactory = (ConfigurationFactory) 
configurationFactoryField.get(webAppBuilder);
Field deployerField = 
configurationFactory.getClass().getDeclaredField("deployer");
deployerField.setAccessible(true);
DynamicDeployer currentDeployer = (DynamicDeployer) 
deployerField.get(configurationFactory);
// HERE: Setting the deployer through reflection, as there's no api 
for setting it.
CyclosDeployer deployer = new CyclosDeployer(currentDeployer);
deployerField.set(configurationFactory, deployer);
} catch (Exception e) {
throw new IllegalStateException(e);
}

* Ok, I had my custom deployer in, but in order to set a custom value for the 
data source, I had a problem: The standard deployer is a 
org.apache.openejb.config.ConfigurationFactory.Chain, with several other 
deployers. The first one is ReadDescriptors and the others would actually 
deploy the beans. However, to change the data source, my deployer would have to 
run after ReadDescriptors (otherwise there would be no knowledge about any 
persistence units), but before the other deployers, or the wrong data source 
would be already deployed when my deployer would be invoked. So, another hack: 
by reflection again, retrieve the Chain's deployers and remove the 
ReadDescriptors from there. Then, my deploy method:
public AppModule deploy(AppModule appModule) throws OpenEJBException {
//The ReadDescriptors must run in order to have persistence modules
new ReadDescriptors().deploy(appModule);

for (PersistenceModule pm : appModule.getPersistenceModules()) {
for (PersistenceUnit unit : 
pm.getPersistence().getPersistenceUnit()) {
if ("cyclos".equals(unit.getName())) {
String path = "/" + 
appModule.getWebModules().get(0).getContextRoot();
String dataSource = dataSources.get(path);
if (dataSource == null) {
throw new IllegalStateException("Could not find the 
datasource for Cyclos instance at " + path);
}
//Set the data source name
unit.setJtaDataSource(dataSource);
unit.setNonJtaDataSource(dataSource + "_nonJta");
}
}
}

return delegate.deploy(appModule);
}

* And, since I was this deep, I've used the ConfigurationFactory / Assembler to 
deploy the DataSource as David suggested, but I could live with a predefined 
data source.

So, here's my de