[jboss-as7-dev] [OSGi WAB support] webbundle: URL handler

David Bosschaert david at redhat.com
Fri Nov 30 11:35:08 EST 2012


I was looking into it a little more too and came to the conclusion that 
the whole approach via the DeploymentUnitProcessor can't work.

The problem is that things passed via a webbundle: URL don't need to be 
OSGi bundles. One of the things that the webbundle: URL handler can do 
is turn non-OSGi bundles (i.e. WAR files) into OSGi bundles on the fly, 
so you could do something like:

bundle.install("webbundle:file://myplainold.war?Bundle-SymbolicName=foo&&Web-ContextPath=/test")

The problem is that from very early on in the process, even before it 
hits the the DUPs, the bundle.install code expects the thing that is 
being deployed to be a valid OSGi bundle. And I think it's right in 
doing that.

So - the only clean solution that I can see is to have the URL handler 
to the conversion to OSGi bundle on the fly. With that you can use these 
webbundle: URLs from anywhere I think as they will work from anywhere in 
the vm where you do URL().openStream().

Cheers,

David

On 30/11/2012 16:22, Thomas Diesler wrote:
> I was thinking about this a little more …
>
> We need to distinguish between two cases
>
> #1 Deployment through CLI, Console, Management API
> #2 Deployment through BundleContext.install(…)
>
> Re #1: In this case the webbundle URI needs to be passed through the 
> mgmnt layer. What happens when you try this in CLI/Console? In both 
> UIs there must be a way to pass in a URI that is then accessible from 
> a DUP.
> Given that we can see the URI in a DUP, it can be parsed after 
> OSGiBundleInfoParseProcessor  but before 
> BundleDeploymentProcessor. The BundleDeploymentProcessor would see 
> valid OSGiMetaData and everything after would proceed as normal.
>
> Re #2: In this case the Framework already provides the Deployment 
> object that is then passed to the BundleLifecycleIntegration. By that 
> time the metadata is already parsed and part of the Deployment. This 
> happens in AbstractBundleContext
>
>           DeploymentFactoryPlugin deploymentPlugin = 
> frameworkState.getDeploymentFactoryPlugin();
>           dep = deploymentPlugin.createDeployment(location, rootFile);
>
> Fortunately the DeploymentFactoryPlugin is an integration point that 
> exits in anticipation of a requirement like this. You would need to 
> provide a "DeploymentFactoryIntegration" that parses the webbundle URI 
> in createDeployment. The returned Deployment is already a valid OSGi 
> deployment. No additional work is needed in the DUPs.
>
> cheers
> --thomas
>
>
> On Nov 30, 2012, at 3:35 PM, Thomas Diesler <thomas.diesler at jboss.com 
> <mailto:thomas.diesler at jboss.com>> wrote:
>
>> Good progress
>>
>> > I can get the Deployment object back, given its DU.name
>>
>> You don't need to do that. Your DUP should be placed after the 
>> BundleDeploymentProcessor, in which case the Deployment is readily 
>> available from the DU.
>>
>> Re the Bundle.location to DU.name mapping …
>> The runtime name must be unique and at the same time simple enough to 
>> be usable as bundle key on the CLI. How about using the something 
>> like this
>>
>> String toRuntimeName(String location) {
>>    - if location is valid URI: return URI path (i.e. strip protocol & 
>> params)
>>    - else if location has a suffix .???: return location without suffix
>>    - else return location
>> }
>>
>>
>> On Nov 30, 2012, at 3:24 PM, David Bosschaert <david at redhat.com 
>> <mailto:david at redhat.com>> wrote:
>>
>>> Ah, yes. Via a static method on BundleLifecycleIntegration I can get 
>>> the Deployment object back, given its DU.name. Once I have the 
>>> Deployment object I can indeed find out the original URL and read 
>>> the parameters off that.
>>>
>>> The getRuntimeName() simply returns the thing after the last "/" in 
>>> the installation location. This may be alright for things that come 
>>> from the filesystem, but if you install something from a URL the 
>>> results can be a bit random, as people can have '/'-es in their 
>>> parameters, e.g.
>>> http://myhost/mybundle?param1=/whatever
>>> I will have a look at making that a bit better in that context.
>>>
>>> I noticed that the DeploymentPlanBuilder.add() has an overload where 
>>> you can provide a name and a common name. This might be useful for 
>>> OSGi in that for the common name we could pass in the name we 
>>> currently do, but for the name we could pass in the original 
>>> Bundle.location argument. I haven't fully tested this but it seems 
>>> to me that that could ensure that even in the case that 
>>> getRuntimeName() returns the same thing for two different bundles 
>>> things will still continue to work.
>>>
>>> Cheers,
>>>
>>> David
>>>
>>> On 30/11/2012 10:55, Thomas Diesler wrote:
>>>> The DU runtime name is computed here 
>>>> <https://github.com/jbosgi/jboss-as/blob/master/osgi/service/src/main/java/org/jboss/as/osgi/service/BundleLifecycleIntegration.java#L284>
>>>>
>>>> LOGGER.debugf("Install deployment: %s", dep);
>>>> String runtimeName = getRuntimeName(dep);
>>>> putDeployment(runtimeName, dep);
>>>> try {
>>>> InputStream input = dep.getRoot().openStream();
>>>> try {
>>>>   ServerDeploymentHelper server = new 
>>>> ServerDeploymentHelper(deploymentManager);
>>>>   server.deploy(runtimeName, input);
>>>>                     } finally {
>>>>   VFSUtils.safeClose(input);
>>>>                     }
>>>>                 } catch (RuntimeException rte) {
>>>> throw rte;
>>>>                 } catch (Exception ex) {
>>>> throw MESSAGES.cannotDeployBundle(ex, dep);
>>>>                 }
>>>>
>>>> That mapping from the Bundle.location to the DU.name is historical 
>>>> and I'm not sure what the limitations currently are. Perhaps you 
>>>> could find out while you're doing this and document why 
>>>> getRuntimeName(dep) is doing what its doing. That name also has to 
>>>> feed through the management layer as the deployment's runtimeName. 
>>>> Perhaps there are some limitations at that level. Have a look at 
>>>> the variations of DeploymentPlanBuilder.add(…)
>>>>
>>>> Ideally, we would like to pass the Bundle.location directly to the 
>>>> DeploymentPlanBuilder API so that it becomes DU.name unchanged.
>>>>
>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>> Thomas Diesler
>>>> JBoss OSGi Lead
>>>> JBoss, a division of Red Hat
>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>>
>>>>
>>>>
>>>> On Nov 30, 2012, at 11:29 AM, Thomas Diesler 
>>>> <thomas.diesler at jboss.com <mailto:thomas.diesler at jboss.com>> wrote:
>>>>
>>>>> > DeploymentUnit.getName() only returns the bare name of the item 
>>>>> being deployed
>>>>>
>>>>> Is this really true? What is the DU.name when you do 
>>>>> BundleContext.install("webbundle://foo?key=value", input) ?
>>>>>
>>>>> > I could not find the Deployment.location
>>>>>
>>>>> Have a look at the BundleDeploymentProcessor 
>>>>> <https://github.com/jbosgi/jboss-as/blob/master/osgi/service/src/main/java/org/jboss/as/osgi/deployment/BundleDeploymentProcessor.java> 
>>>>>
>>>>>
>>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>>> Thomas Diesler
>>>>> JBoss OSGi Lead
>>>>> JBoss, a division of Red Hat
>>>>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>>>>
>>>>>
>>>>>
>>>>> On Nov 29, 2012, at 10:11 PM, David Bosschaert <david at redhat.com 
>>>>> <mailto:david at redhat.com>> wrote:
>>>>>
>>>>>> Hi Thomas,
>>>>>>
>>>>>> If I can get the original location/URI back in the 
>>>>>> DeploymentUnitProcessor.deploy() so I can associate them with 
>>>>>> each other that would work for me too. DeploymentUnit.getName() 
>>>>>> only returns the bare name of the item being deployed (e.g. just 
>>>>>> "mywebapp"), which isn't really precise enough. I could not find 
>>>>>> the Deployment.location that you're referring to from the 
>>>>>> deploy() method, is it available as an attachment of some sort?
>>>>>>
>>>>>> Cheers,
>>>>>>
>>>>>> David
>>>>>>
>>>>>> On 29/11/2012 19:22, Thomas Diesler wrote:
>>>>>>> Hi David,
>>>>>>>
>>>>>>> The webbundle://foo?key=value URL is mainly a transport vehicle 
>>>>>>> for meta data. I don't think it is intended to give access to 
>>>>>>> the bytes of the war (however, we could do this too - see 
>>>>>>> below). That URL spec (as a string) is the Bundle.location that 
>>>>>>> is given in BundleContext(location, input). That location 
>>>>>>> identifier was originally meant to be a URL that could give 
>>>>>>> access to the Bundle's bytes. This is no longer the case and any 
>>>>>>> string (in most cases an URI) can be given as the location. 
>>>>>>> Internally, I think the location becomes the DU name. If not, it 
>>>>>>> is definitely the Deployment.location.
>>>>>>>
>>>>>>> So a DUP does have access to that web bundle location. The URL 
>>>>>>> handler is mainly a URI parser that is supposed to give access 
>>>>>>> to the OSGi metadata that need to be put in the manifest (in our 
>>>>>>> case the OSGiMetaData not the Manifest). AFAIK, the Framework 
>>>>>>> tries to construct a URL from the location only if no input 
>>>>>>> bytes are given. When we talk about an URLHandler we are mainly 
>>>>>>> talking about a simple URI parser. A URLHandler would need to be 
>>>>>>> implemented for BundleContext(location) to work.
>>>>>>>
>>>>>>> Given that the URI parsing works and that we can generate 
>>>>>>> OSGiMetaData from it, the bytes that make up the WAR are 
>>>>>>> maintained by the DeploymentRepository and available through the 
>>>>>>> DU roots.
>>>>>>>
>>>>>>> In the unlikely case that the TCK does something like this:
>>>>>>>
>>>>>>> Manifest  manifest = new Manifest(new 
>>>>>>> URL("webbundle://foo?key=value").openStream());
>>>>>>>        validateGeneratedManifest(manifest)
>>>>>>>
>>>>>>> we would need to feed back the generated OSGiMetaData to a byte 
>>>>>>> buffer. In any case that would have to access the DU root 
>>>>>>> content and amend it by a generated Manifest.
>>>>>>> I'd have to check if the above is really required.
>>>>>>>
>>>>>>> If this does not help either, give me a shout and I put together 
>>>>>>> a quick prototype.
>>>>>>>
>>>>>>> cheers
>>>>>>> --thomas
>>>>>>>
>>>>>>>
>>>>>>> On Nov 29, 2012, at 12:29 PM, David Bosschaert <david at redhat.com 
>>>>>>> <mailto:david at redhat.com>> wrote:
>>>>>>>
>>>>>>>> Hi Thomas,
>>>>>>>>
>>>>>>>> I have the following issues with your suggestion.
>>>>>>>>
>>>>>>>> 1. I don't fully see how the information available to the URL 
>>>>>>>> handler can be associated with the information available to the 
>>>>>>>> DeploymentUnitProcessor. The URL handler has the URL, that's 
>>>>>>>> all, while AFAICS the original URL (or whatever was inside the 
>>>>>>>> webbundle: url) is no longer available when the deploy() method 
>>>>>>>> is called.
>>>>>>>> 2. If we find a way to fix 1. this will only work if people use 
>>>>>>>> BundleContext.install(String location). It will fail when 
>>>>>>>> people call url.openStream() on the webbundle: url and does not 
>>>>>>>> work with BundleContext.install(String, InputStream).
>>>>>>>>
>>>>>>>> Another approach would be to simply let the URL handler do all 
>>>>>>>> the work, i.e. modify the stream being passed through. Then 
>>>>>>>> those URLs will work in any context.
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>>
>>>>>>>> David
>>>>>>>>
>>>>>>>> On 26/11/2012 17:25, Thomas Diesler wrote:
>>>>>>>>> Hi David,
>>>>>>>>>
>>>>>>>>> here a quick summary of what I suggested today:
>>>>>>>>>
>>>>>>>>> The first thing that sees the URL coming from 
>>>>>>>>> BundleContext.install(...) is the Framework, which has a 
>>>>>>>>> notion of pluggable URL handlers.
>>>>>>>>> In AS7 the URL handler should be an integration plugin and a 
>>>>>>>>> DUP at the same time. The DUP would do nothing as long as the 
>>>>>>>>> plugin
>>>>>>>>> is not activated (i.e. the framework is down). When the 
>>>>>>>>> Framework activates the URL handler gets registered with the 
>>>>>>>>> framework and the DUP becomes active.
>>>>>>>>>
>>>>>>>>> The DUP would then need to provide OSGiMetaData with a 
>>>>>>>>> Bunde-SymbolicName and Bundle-Classpath. The Bundle-Classpath 
>>>>>>>>> should point to WEB-INF/classes and
>>>>>>>>> the collection of stuff in WEB-INF/lib. For completeness it 
>>>>>>>>> could generate Package-Import requirements on the 
>>>>>>>>> javax.servlet.* APIs. The DUP should be placed after
>>>>>>>>> the DUP that normally provides OSGiMetaData and should do 
>>>>>>>>> nothing if the OSGiMetaData is already there.
>>>>>>>>>
>>>>>>>>> Hope that helps, cheers
>>>>>>>>> --thomas
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 11/21/2012 05:58 PM, David Bosschaert wrote:
>>>>>>>>>> Hi all,
>>>>>>>>>>
>>>>>>>>>> As part of making the JBoss OSGi Web Application Support 
>>>>>>>>>> compliant with
>>>>>>>>>> the spec I have started running it through the OSGi TCK.
>>>>>>>>>> I noticed that the TCK depends heavily on the webbundle: URL 
>>>>>>>>>> protocol
>>>>>>>>>> which is specified in section 128.4 of the specification - it 
>>>>>>>>>> is not an
>>>>>>>>>> optional piece. So in order to support this we need to 
>>>>>>>>>> provide such a
>>>>>>>>>> URL handler.
>>>>>>>>>>
>>>>>>>>>> As the webbundle: handler is never part of runtime operation 
>>>>>>>>>> (it only
>>>>>>>>>> converts a WAR file into a WAB file on the fly) I was looking 
>>>>>>>>>> into
>>>>>>>>>> possibly using existing implementations of the URL handler 
>>>>>>>>>> instead.
>>>>>>>>>> However the ones that I found are quite heavy on the 
>>>>>>>>>> dependencies. The
>>>>>>>>>> implementation in Aries depends on Blueprint being present 
>>>>>>>>>> and the one
>>>>>>>>>> in Pax has about 10 other dependencies (including junit) - 
>>>>>>>>>> they drag in
>>>>>>>>>> too much baggage IMHO.
>>>>>>>>>>
>>>>>>>>>> So I'm starting to come to the conclusion that we need to 
>>>>>>>>>> provide such
>>>>>>>>>> an implementation as part of the OSGi webbundle support in 
>>>>>>>>>> AS7. The JIRA
>>>>>>>>>> is https://issues.jboss.org/browse/AS7-6006
>>>>>>>>>>
>>>>>>>>>> Any other ideas?
>>>>>>>>>>
>>>>>>>>>> Cheers,
>>>>>>>>>>
>>>>>>>>>> David
>>>>>>>>>> _______________________________________________
>>>>>>>>>> jboss-as7-dev mailing list
>>>>>>>>>> jboss-as7-dev at lists.jboss.org 
>>>>>>>>>> <mailto:jboss-as7-dev at lists.jboss.org>
>>>>>>>>>> https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> jboss-as7-dev mailing list
>>>>> jboss-as7-dev at lists.jboss.org <mailto:jboss-as7-dev at lists.jboss.org>
>>>>> https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
>>>>
>>>
>>
>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>> Thomas Diesler
>> JBoss OSGi Lead
>> JBoss, a division of Red Hat
>> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>>
>>
>>
>> _______________________________________________
>> jboss-as7-dev mailing list
>> jboss-as7-dev at lists.jboss.org <mailto:jboss-as7-dev at lists.jboss.org>
>> https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
>
> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Thomas Diesler
> JBoss OSGi Lead
> JBoss, a division of Red Hat
> xxxxxxxxxxxxxxxxxxxxxxxxxxxx
>
>
>



More information about the jboss-as7-dev mailing list