Return-Path: Delivered-To: apmail-geronimo-dev-archive@www.apache.org Received: (qmail 21423 invoked from network); 25 May 2010 10:18:25 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 25 May 2010 10:18:25 -0000 Received: (qmail 40217 invoked by uid 500); 25 May 2010 10:18:25 -0000 Delivered-To: apmail-geronimo-dev-archive@geronimo.apache.org Received: (qmail 39975 invoked by uid 500); 25 May 2010 10:18:22 -0000 Mailing-List: contact dev-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list dev@geronimo.apache.org Received: (qmail 39968 invoked by uid 99); 25 May 2010 10:18:22 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 May 2010 10:18:22 +0000 X-ASF-Spam-Status: No, hits=1.1 required=10.0 tests=AWL,FREEMAIL_FROM,HK_RANDOM_ENVFROM,HK_RANDOM_FROM,RCVD_IN_DNSWL_NONE,SPF_PASS,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: apache.org Received-SPF: pass (athena.apache.org: domain of rickmcg@gmail.com designates 209.85.212.54 as permitted sender) Received: from [209.85.212.54] (HELO mail-vw0-f54.google.com) (209.85.212.54) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 May 2010 10:18:14 +0000 Received: by vws18 with SMTP id 18so1959898vws.13 for ; Tue, 25 May 2010 03:17:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:reply-to :user-agent:mime-version:to:subject:references:in-reply-to :content-type:content-transfer-encoding; bh=tDXx0G23ZXWn917g28m3uf851LUdJxUqDt3grqWl/sA=; b=U+o41HP6mEPTpuJgYaVFXPMvVzbCgBMEv13oYuh8o1f4D0D/1fTCiPQiUAy5pAsV96 kGz4BzWVA54UTuYvdyGn0Ash8v4cLPcnMhixTonDZp6sZX6Wd0tzLp9KFT5JvC0qS4Ub FOR80rrCs03NBVgvnKqrsTMXVZT6e/psw5cSc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:reply-to:user-agent:mime-version:to:subject :references:in-reply-to:content-type:content-transfer-encoding; b=nB67GnzBqSWJ4t1UBHImj+wDCgOGNThN+LXbArxeY7VSUGrsZM8/cPtct9prAzO2U3 EKBpR2sryCa/aGAUxZNrBWUyaNHW7dFIRvRJGmMn5KKPGaHsRQF0AuNrgu0F2ZatA/Rs THEWfvbO7Ks6Rp0PdM0jqmn57Z66PfZyhstTU= Received: by 10.220.61.201 with SMTP id u9mr4827416vch.180.1274782673510; Tue, 25 May 2010 03:17:53 -0700 (PDT) Received: from [192.168.1.100] (24-151-82-15.dhcp.nwtn.ct.charter.com [24.151.82.15]) by mx.google.com with ESMTPS id v12sm23380393vch.21.2010.05.25.03.17.51 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 25 May 2010 03:17:52 -0700 (PDT) Message-ID: <4BFBA3CE.7020405@gmail.com> Date: Tue, 25 May 2010 06:17:50 -0400 From: Rick McGuire Reply-To: rickmcg@gmail.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4 MIME-Version: 1.0 To: dev@geronimo.apache.org Subject: Re: Adding OSGi support to Geronimo spec jars. References: <4B87CE2A.9060008@gmail.com> In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit On 5/24/2010 8:06 PM, David Blevins wrote: > On May 24, 2010, at 3:49 PM, David Jencks wrote: > > >> On May 24, 2010, at 2:18 PM, David Blevins wrote: >> >> >>> 1. Using EJB as an example, how does one say "I am a provider". There is no "i am the EJB container" interface to implement so what exactly are we looking for? >>> >> >> EJB is not an example. the provider stuff works for 2 situations: >> > The activator and locator were added to the EJB spec jar. Was that a mistake? > I don't believe it was. There are two sides to this generally. The first side is the role played by the specs, which generally need to locate a provider. Typically, the specification defines a search path that generally searches for 1) a META-INF/services definition, 2) a class defined in a properties file, and 3) a system property. Depending on the age of the specification, the order in which these 3 are searched will vary, and the newest java ee components only define step 1. Generally, this search order will resolve to the name of a provider class that the API code will then instantiate to create the provider instance. The second role is that of the provider class itself. Typically, a provider jar would use the META-INF/services mechanism to advertise its availability. The java EE defined mechanism for locating the provider is to search the classpath for an appropriate META-INF/services file and load the first definition it locates. In an OSGi environment, there are a number of problems associated with the "search the classpath" step, so the ProviderLocator was created. There are two pieces to this: 1) A provider registry. This is an extender that watches new bundles being activated, and if the bundle contains the appropriate metadata, then then the services it exports are made part of a framework-wide registry. 2) The ProviderLocator. This is how APIs that need to resolve providers access the registry information. The provider registry is an OSGi service, so the ProviderLocator needs a bundle context instance to resolve the service instance. The Activator manages obtaining the bundle context at activation and setting up a service tracker to give access to the registry service. The ProviderLocator code manages the details of locating a loading a service instance and will revert to classic classpath behavior if used outside of an OSGi environment. There are two different models in play here for locating a provider instance. In the first model, the API has been handed the name of the desired provider directly as a class name. The API could would then attempt to instantiate that class directly (typically by using the thread context classloader). In the second model, an appropriate META-INF/services definition is located using the interface that the provider is expected to implement as the search key. The services definition file provides a mapping to the provider class name, which is then loaded and instantiated. In terms of my search paths defined in the first paragraph above, 1) is the META-INF/services mode, and 2) and 3) are the first mode of direct loading. The provider registry can handle either of these locator modes. If your provider is already using a META-INF/services model, then the registry then generally all you need to do is add an SPI-Provider header to your jar file. Openejb should have this already, but the EJB3 spec code is not strictly following the EJB specification for locating the provider, so it is possible it is not. If your provider needs to be located via a direct load mechanism where the class name is provided, then you can use an Export-Service-Provider header to advertise your provider class so the ProviderLocator code can locate it by name. So, what should the openejb code be doing? The best solution would be to create the META-INF/services file that maps EJBContainerProvider to your implementation class and add the SPI-Provider header. Unfortunately, there is a gotcha here, in the form of this Jira: https://issues.apache.org/jira/browse/GERONIMO-5186 The EJB specification says the EJBContainerProvider lookup mechanism should use only the META-INF/services mechanism, and for each definition if finds, it should instantiate the service instance and call createEJBContainer() passing the property bundle that was passed to EJBContainer.createEJBContainer(). The provider instance is then responsible for determining if it is the appropriate provider by examining the provider name in the properties bundle. Here's the wording from the spec: The EJBContainer bootstrap class will locate all of the container providers by their provider configuration files and call EJBContainerProvider.createEJBContainer(Map) on them in turn until an appropriate backing provider returns an EJBContainer. A provider may deem itself as appropriate for the embeddable application if any of the following are true : �The javax.ejb.embeddable.provider property was included in the Map passed to createEJBContainer and the value of the property is the provider's implementation class. �No javax.ejb.embeddable.provider property was specified. If a provider does not qualify as the provider for the embeddable application, it must return null when createEJBContainer is invoked on it. Unfortunately, the search mechanism in the Geronimo EJBContainer class short-cuts this mechanism and checks the provider property directly and uses that information to directly load the provider class rather than using the META-INF/services mechanism. I'm guessing this is the normal mode of operation for openejb. In that case, you need to be using the Export-Service-Provider header. I would really like to fix this Jira, but this requires a bit of rework in the EJBContainer.createEJBContainer() method. Rework that would break OpenEJB as it exists in its current state. I think the issues in OpenEJB need to be fixed first, then the spec behavior can be fixed. Here's what I think needs to be done in OpenEJB: 1) Add the META-INF/services definition mapping the EJBContainerProvider to the implementation class. 2) Add the SPI-Provider header to opt in to the services registry for this definition. 3) Add the Export-Service-Provider header to the bundle to also export the provider class explicitly. 4) Ensure that the implementation of createEJBContainer() properly implements the behavior of returning null if it is not the correct provider for the provided configuration. Assuming this is done, then the spec class can be changed to be compliant without breaking openejb. During the transitional period, the Export-ServiceProvider header will allow the provider class to be loaded using the current spec implementation, and after the Jira is fixed, META-INF/services mapping will allow it to revert to the specified mechanism. Rick > > -David > > >