I usually just grab the *Factory object from the service registry
as per the XML Parsers part of the specification. Equinox (IIRC)
publishes the factories into the service registry, but some
frameworks do not.

In those cases, I just implemented the specification myself in a
separate bundle. My activator would grab the default returned by
*ParserFactory.newInstance() and publish it into the service
registry.

I'm not sure that this is the correct solution though, but it
worked for me on Apache Felix. At least if you do this, you can
re-wire the factory for different implementations based on
service properties, and have different implementations running in
the same "application".

Chris Armstrong

On Tue, 12 Oct 2010 23:04 -0400, "David M Williams"
<[email protected]> wrote:

  In general, this is a pretty well known issue. Well enough
  known that OSGi has a special section of their spec to cover
  it.
  Well, at least for the Parser cases .... I don't recall seeing
  anything for Transformer, but I think the issues and
  principles
  are the same. So, if you didn't know that, you might find
  interesting the 'XML Parser Service Specification' section of
  the
  [1]Compendium Specification
  [2]http://www.osgi.org/download/r4v42/r4.cmpn.pdf
  Also, you might study through bugs and code in Equinox related
  to this (again, I know of parser cases .. would be
  similar for Transformer, I suspect, if Transformer was
  spec'd). Such as see
  [3]https://bugs.eclipse.org/bugs/show_bug.cgi?id=285505
  At its heart, equinox provides the context classloader
  solution (again, for parsers).
  The bugzilla entry also provides links to some other xml
  commons bugs that are interesting from an OSGi point of view,
  though again, not directly related to solving your problem.
  Also be aware that Eclipse Orbit offers some "OSGi'ed"
  versions of xmlcommons libraries, but do not modify
  code or provide a service. Such as see
  http://download.eclipse.org/tools/orbit/downloads/drops/R20100
  519200754/
  I'm not saying these would solve your problem ... but, if you
  create your own bundles, beware of "conflicts" with
  other bundles out in the wild.
  I am no OSGi expert, but I'd think you could provide a service
  to create your new instance, any way you want,
  and that'd be preferable to changing someone else's
  "newInstance" code ...
  but then application code would have to know to use your
  service (not sure if you were ruling that out, or not).
  I'm not sure the problem can be solved, without application
  code knowing how/which service to call, but
  best of luck.
  From:        Lindsay Smith <[email protected]>
  To:        "[email protected]" <[email protected]>
  Date:        10/11/2010 04:33 PM
  Subject:        [osgi-dev] XML libraries -
  TransformerFactory.newInstance and        friends
  Sent by:        [email protected]
    _________________________________________________________

  I've run into some issues with the standard XML libraries.
  Calls like this:

  TransformerFactory.newInstance()

  are particularly unsuited to the OSGI environment.  The above
  call, for example, attempts to identify the name of the class
  to instantiate from a number of locations.  These are:

  1) The value of a system property
  2) The presence of some properties file in java.home
  3) The presence of a resource under META-INF/services accessed
  through the context ClassLoader

  Once the name of the class is found, the context ClassLoader
  is used to instantiate it.

  The first two locations are especially nasty in an OSGI
  environment, as it can mean that the factory looks up the name
  of the class from a location completely unrelated to the class
  space in which the class will be instantiated.  The third
  location can be made to work - as the context ClassLoader can
  be set to the current bundle ClassLoader prior to calling, and
  frameworks (like spring dm) often set it this way too.

  The product that I develop has recently moved to using OSGI
  for class isolation and modularity, and it's a great fit.  One
  of the advantages we see in using OSGI is the ability to
  isolate your application from its environment.  This is
  particularly important when you don't have control over the
  deployment environment e.g. the application is to be installed
  on a client site where the java or servlet container
  environment managed by another IT department.

  OSGI has definitely delivered benefits to us in keeping our
  code isolated from the environment but patterns such as the
  TransformerFactory.newInstance() situation still give us
  problems.  In some situations the web container or even a
  sibling application sets the associated system property, and
  our application is then broken because the named class is not
  visible to us.

  In our own code we use direct constructor of the xml library
  we wish to instantiate to prevent this happening.  However
  sometimes libraries we include new the newInstance() method
  (spring dm is the main offender here - the spring beans
  parser), and we can't change them.

  One thing we have done to standardise the xml libraries used
  inside our application is to remove all the javax.xml.*
  packages from the system packages list, and to include apache
  xmlcommons, resolver, and xerces bundles found in the
  springsource repository e.g:

  [4]http://www.springsource.com/repository/app/bundle/version/d
  etail?name=com.springsource.org.apache.xmlcommons&version=1.3.
  4

  This standardises the xml apis across all jvms, but the
  newInstance() problem remains.

  I was thinking about modifying the newInstance() methods in
  the xmlcommons bundle to be correct for an OSGI environment.
  In the first instance I was simply going to change the search
  order so that the META-INF/services step comes first, as this
  can be controlled in our bundles.   However I was wondering
  how I could go about making a full OSGI implementation of this
  system.  It could do something like:

  1) Return an instance of a TransformerFactory service if one
  exists (I guess the highest version available if multiple)
  2) Use the META-INF/services location of the context
  ClassLoader
  3) Read the OSGI framework properties (rather than system
  properties)

  So, some questions:

  Has anyone else had this problem and overcome it without
  requiring changes to the application environment?
  Would an OSGI version of xmlcommons be useful to anyone else?

  How should it be designed? Is the above search order sensible?
   Anything else that would make sense within an OSGI runtime?

  Regards

  Lindsay Smith

   _______________________________________________
  OSGi Developer Mail List
  [email protected]
  [5]https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

References

1. http://www.osgi.org/Download/File?url=/download/r4v42/r4.cmpn.pdf
2. http://www.osgi.org/download/r4v42/r4.cmpn.pdf
3. https://bugs.eclipse.org/bugs/show_bug.cgi?id=285505
4. 
http://www.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.apache.xmlcommons&version=1.3.4
5. https://mail.osgi.org/mailman/listinfo/osgi-dev
-- 
  Christopher Armstrong
  carmstrong ^^AT^ fastmail dOT com /Dot/ au

_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to