Mark, Thanks for the info. Just as a side note we are using EMF with CDO here and I'll double check but I believe we have this correctly managed, but I'm aware of some CME issues that can sometimes happen, even in a normal RCP application when dealing with itemProviders for example.
Cheers, Alain On Wed, Mar 11, 2020 at 10:18 AM Mark Hoffmann via osgi-dev < osgi-dev@mail.osgi.org> wrote: > Hi Alain, > > a little bit late but maybe some side notes to EMF and OSGi. EMF is not > thread-safe. May it be possible that you share one ResourceSet/Resource > over many Prototype instances? > > This is in general not a good idea. In case you use EMF with Equinox, you > should give each prototype instance an own ResourceSet instance. Otherwise > you will sooner or later run into ConcurrentModificationException when > adding/removing Resources to/from a ResourceSet. In any case sharing a > ResourceSet over Prototype instance will also lead to memory leaking over > the time, if you do not remove/cleanup the Resources after using them. > > Using EObjects in a detached state can be helpful, but is not useful for > some use-cases e.g. Validation / Compare, because you have to attach the > objects before doing something. > > You can also take look at our GeckoEMF. We have ResourceSets as a service, > also as PROTOTYPE scoped. So you can get an own ResourceSet instance > injected. We also have a ResourceSetFactory, that can create ResourceSets. > This solves many problems using EMF in pure OSGi. There is also a > Thread-safe ResourceSet implementation regarding the usage of Resources > > https://gitlab.com/gecko.io/geckoEMF > > Mark > Am 11.03.20 um 13:26 schrieb Alain Picard via osgi-dev: > > Peter and Tim, > > Thanks for the pointers. The error was caused by some invalid use of a > disposed object. This was using factory components and I switched all of it > to use prototype components instead which IMHO are easier to manage. > > And Peter to your question about using prototype scope, those objects > contain state and it is my understanding that prototype scope is required > in those cases. > > Thanks > Alain > > > On Mon, Mar 2, 2020 at 9:39 AM Peter Kriens <peter.kri...@aqute.biz> > wrote: > >> Some remarks: >> >> * Yes, it is thread safe. In OSGi we mark all thread safe types with the >> @ThreadSafe annotation. >> * The error message is not in the log you listed. Since the log contains >> a deactivation message, I hope you're handling the case corrected that >> you're being called after deactivation? Seems too simple, but anyway ... :-) >> >> * And for something completely different, is there any reason you use the >> prototype scope? You real code might need it but for this code it just >> looks like making it accidentally complex? >> * And last but not least, you seem to be using slf4j? Did you wire up the >> OSGi log to it? I've seen cases where the information was in the OSGi log >> but those messages were discarded. >> >> Kind regards, >> >> Peter Kriens >> >> >> On 2 Mar 2020, at 12:03, Alain Picard via osgi-dev < >> osgi-dev@mail.osgi.org> wrote: >> >> Question: The method getDiagnosticForEObject can be called by different >> threads. Can this be the source of the issue? I see that >> ComponentServiceObject is tagged as ThreadSafe, but? >> >> Alain >> >> >> On Mon, Mar 2, 2020 at 5:47 AM Alain Picard <pic...@castortech.com> >> wrote: >> >>> Tim, >>> >>> I don't think so. BaValidationManagerExt is used in only 1 place and it >>> is instantiated in activate and released in deactivate: >>> @Component( >>> factory = ValidationManager.CONFIG_FACTORY, >>> service = ValidationManager.class >>> ) >>> public final class CoreValidationManager extends >>> CDODefaultTransactionHandler1 implements ValidationManager, >>> CDOTransactionHandler2 { >>> ... >>> @Reference(scope=ReferenceScope.PROTOTYPE_REQUIRED) >>> private ComponentServiceObjects<ValidationManagerExt> extenderFactory; >>> private ValidationManagerExt extender; >>> >>> @Activate >>> private void activate() { >>> log.trace("Activating {}", getClass()); //$NON-NLS-1$ >>> >>> extender = extenderFactory.getService(); >>> } >>> >>> @Deactivate >>> private void deactivate() { >>> log.trace("Deactivating {}", getClass()); //$NON-NLS-1$ >>> extenderFactory.ungetService(extender); >>> } >>> >>> Cheers, >>> Alain >>> >>> Alain Picard >>> Chief Strategy Officer >>> Castor Technologies Inc >>> o:514-360-7208 >>> m:813-787-3424 >>> >>> pic...@castortech.com >>> www.castortech.com >>> >>> >>> On Mon, Mar 2, 2020 at 3:40 AM Tim Ward <tim.w...@paremus.com> wrote: >>> >>>> Hi Alain, >>>> >>>> Is it possible that someone has a reference to a BaValidationManagerExt >>>> service instance that they aren’t releasing after ungetting it (or that >>>> they’re holding onto after it has been unregistered)? It might be an SCR >>>> bug, but it’s more likely to be some code holding onto a component instance >>>> that it shouldn’t. >>>> >>>> Best Regards, >>>> >>>> Tim >>>> >>>> On 29 Feb 2020, at 13:29, Alain Picard via osgi-dev < >>>> osgi-dev@mail.osgi.org> wrote: >>>> >>>> Hi >>>> >>>> I am having a very intermittent issue with getService on a prototype >>>> component. This is called hundreds of times and I put a breakpoint a few >>>> weeks ago and have now gotten the error. >>>> >>>> I have this class: >>>> @Component(scope=ServiceScope.PROTOTYPE, >>>> property= org.osgi.framework.Constants.SERVICE_RANKING + ":Integer=10" >>>> ) >>>> public final class BaValidationManagerExt implements >>>> ValidationManagerExt { >>>> private final Logger log = LoggerFactory.getLogger(getClass()); >>>> >>>> @Reference(scope = ReferenceScope.PROTOTYPE_REQUIRED) >>>> private ComponentServiceObjects<Validator> validatorFactory; >>>> >>>> @Activate >>>> private void activate() { >>>> log.trace("Activating {}/{}", getClass(), >>>> System.identityHashCode(this)); //$NON-NLS-1$ >>>> } >>>> >>>> @Deactivate >>>> private void deactivate() { >>>> log.trace("Deactivating {}/{}", getClass(), >>>> System.identityHashCode(this)); //$NON-NLS-1$ >>>> } >>>> .... >>>> @Override >>>> public Diagnostic getDiagnosticForEObject(EObject eObj) { >>>> log.trace("Getting diagnostic for {}", eObj); //$NON-NLS-1$ >>>> Validator validator = validatorFactory.getService(); >>>> >>>> if (validator != null) { >>>> try { >>>> return validator.runValidation(false, Collections.singletonMap(eObj, >>>> new HashSet<>()), >>>> new NullProgressMonitor()).getB(); >>>> } >>>> finally { >>>> validatorFactory.ungetService(validator); >>>> } >>>> } >>>> else { >>>> log.error("Validator Service not found for {}", eObj, new Throwable()); >>>> //$NON-NLS-1$ >>>> return Diagnostic.CANCEL_INSTANCE; >>>> } >>>> } >>>> } >>>> >>>> and the validator: >>>> @Component( >>>> scope = ServiceScope.PROTOTYPE, >>>> property= org.osgi.framework.Constants.SERVICE_RANKING + ":Integer=10" >>>> ) >>>> public final class BaValidator implements Validator { >>>> private final Logger log = LoggerFactory.getLogger(getClass()); >>>> >>>> private Map<EObject, Set<EObject>> elementsToValidate; >>>> private Set<EObject> validated = Sets.newHashSet(); >>>> private boolean batch; >>>> >>>> private EditingDomain domain; >>>> private AdapterFactory adapterFactory; >>>> >>>> @Reference >>>> private volatile List<ValidationProvider> validationProviders; >>>> //NOSONAR as per OSGi 112.3.9.1 >>>> >>>> @Reference >>>> private ValidationUtils validationUtils; >>>> >>>> @Activate >>>> private void activate() { >>>> log.trace("Activating {}/{}", getClass(), >>>> System.identityHashCode(this)); //$NON-NLS-1$ >>>> } >>>> >>>> @Deactivate >>>> private void deactivate() { >>>> log.trace("Deactivating {}/{}", getClass(), >>>> System.identityHashCode(this)); //$NON-NLS-1$ >>>> } >>>> ... >>>> } >>>> >>>> The error is on the highlighted line, which happens since getService >>>> returns null. >>>> >>>> As can be seen here, ValidatorFactory serviceObjects is null which >>>> seems to be what makes it return null: >>>> ComponentServiceObjectsImpl [instances=[], serviceObjects=null, >>>> deactivated=false, hashCode=301166435] >>>> >>>> I am not seeing any special in the logs (tracing is on). Just before I >>>> see a number of successful call to the same code with the last one being: >>>> just before in the logs: >>>> 08:00:45.854 [Worker-1: Create Diagram] TRACE c.c.i.v.b.p.BaValidator - >>>> Activating class >>>> com.castortech.iris.validation.ba.provider.BaValidator/1297753057 >>>> 08:00:45.857 [Worker-1: Create Diagram] TRACE c.c.i.v.b.p.BaValidator - >>>> Notify 4 listeners with diagnostics ([Diagnostic OK >>>> source=com.castortech.iris.ba.validation code=0 >>>> data=[RadialDiagramImpl{[cdoID->6558b1f9-dbcf-4e9d-b7b8-73779b5ada8f] >>>> 08:00:45.858 [Worker-1: Create Diagram] TRACE c.c.i.v.b.p.BaValidator - >>>> Deactivating class >>>> com.castortech.iris.validation.ba.provider.BaValidator/1297753057 >>>> >>>> >>>> Has anyone seen this before or can provide some pointers to address >>>> and/or debug this. >>>> >>>> Thanks >>>> Alain >>>> >>>> _______________________________________________ >>>> OSGi Developer Mail List >>>> osgi-dev@mail.osgi.org >>>> https://mail.osgi.org/mailman/listinfo/osgi-dev >>>> >>>> >>>> _______________________________________________ >> OSGi Developer Mail List >> osgi-dev@mail.osgi.org >> https://mail.osgi.org/mailman/listinfo/osgi-dev >> >> >> > _______________________________________________ > OSGi Developer Mail > listosgi-...@mail.osgi.orghttps://mail.osgi.org/mailman/listinfo/osgi-dev > > -- > Mark Hoffmann > M.A. Dipl.-Betriebswirt (FH) > Geschäftsführer > > Tel: +49 3641 384 910 0 > Mobil: +49 175 701 2201 > E-Mail: m.hoffm...@data-in-motion.biz > Web: www.datainmotion.de > > Data In Motion Consulting GmbH > Kahlaische Straße 4 > 07745 Jena > > Geschäftsführer > Mark Hoffmann > Jürgen Albert > > Jena HRB 513025 > Steuernummer 162/107/05779 > USt-Id DE310002614 > > > > _______________________________________________ > OSGi Developer Mail List > osgi-dev@mail.osgi.org > https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev