Uploaded image for project: 'HiveMind'
  1. HiveMind
  2. HIVEMIND-99

ObjectProvider.provideObject() called twice for a single request

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 1.1
    • 1.1
    • framework
    • None
    • jdk 1.5, Win2k

    Description

      I wrote an object provider for injecting web services into another service.
      This hivemind fragment shows it declaration:
      <service-point id="PingHolder" interface="de.compeople.spirit.communication.base.mikrokernel.objectprovider.IPingHolder">
      <invoke-factory>
      <construct class="de.compeople.spirit.communication.base.mikrokernel.objectprovider.PingHolder" autowire-services="false">
      <object>web-service:Ping</object>
      </construct>
      </invoke-factory>
      </service-point>

      A web service has a logical name (Ping) and its type is derived from the injected property/contructor parameter.
      This provider works quite well, but while debugging I recognised that the provideObject() method within the object provider
      is called twice. From eclipse I have the two stacktraces where it stops (breakpoint) in the object provider:

      Thread [main] (Suspended (breakpoint at line 42 in de.compeople.spirit.communication.base.microkernel.objectprovider.WebServiceObjectProvider))
      de.compeople.spirit.communication.base.microkernel.objectprovider.WebServiceObjectProvider.provideObject(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: 42
      $ObjectProvider_1027bec98d2.provideObject(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: not available
      org.apache.hivemind.service.impl.ObjectTranslator.translate(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: 75
      $Translator_1027bec98c2.translate(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: not available
      org.apache.hivemind.service.impl.BuilderPropertyFacet.getFacetValue(org.apache.hivemind.ServiceImplementationFactoryParameters, java.lang.Class) line: 41
      org.apache.hivemind.service.impl.BuilderFactoryLogic.instantiateExplicitConstructorInstance(java.lang.Class, java.util.List) line: 135
      ===========
      org.apache.hivemind.service.impl.BuilderFactoryLogic.instantiateCoreServiceInstance() line: 112
      org.apache.hivemind.service.impl.BuilderFactoryLogic.createService() line: 77
      org.apache.hivemind.service.impl.BuilderFactory.createCoreServiceImplementation(org.apache.hivemind.ServiceImplementationFactoryParameters) line: 42
      org.apache.hivemind.impl.InvokeFactoryServiceConstructor.constructCoreServiceImplementation() line: 84
      org.apache.hivemind.impl.servicemodel.SingletonServiceModel(org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl).constructCoreServiceImplementation() line: 106
      org.apache.hivemind.impl.servicemodel.SingletonServiceModel(org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl).constructNewServiceImplementation() line: 156
      org.apache.hivemind.impl.servicemodel.SingletonServiceModel(org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl).constructServiceImplementation() line: 138
      org.apache.hivemind.impl.servicemodel.SingletonServiceModel.getActualServiceImplementation() line: 68
      $IPingHolder_1027bec98eb._service() line: not available
      $IPingHolder_1027bec98eb.getPing() line: not available
      $IPingHolder_1027bec98ea.getPing() line: not available
      de.compeople.spirit.communication.base.mikrokernel.objectprovider.WebServiceObjectProviderUsageTest.testBuildWebServiceWithoutTimeoutAndConstructorInjection() line: 39
      sun.reflect.NativeMethodAccessorImpl.invoke0(java.lang.reflect.Method, java.lang.Object, java.lang.Object[]) line: not available [native method]
      sun.reflect.NativeMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 39
      sun.reflect.DelegatingMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 25
      java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 585
      de.compeople.spirit.communication.base.mikrokernel.objectprovider.WebServiceObjectProviderUsageTest(junit.framework.TestCase).runTest() line: 154
      de.compeople.spirit.communication.base.mikrokernel.objectprovider.WebServiceObjectProviderUsageTest(junit.framework.TestCase).runBare() line: 127
      junit.framework.TestResult$1.protect() line: 106
      junit.framework.TestResult.runProtected(junit.framework.Test, junit.framework.Protectable) line: 124
      junit.framework.TestResult.run(junit.framework.TestCase) line: 109
      de.compeople.spirit.communication.base.mikrokernel.objectprovider.WebServiceObjectProviderUsageTest(junit.framework.TestCase).run(junit.framework.TestResult) line: 118
      org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(java.lang.String[], java.lang.String) line: 598
      org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run() line: 354
      org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(java.lang.String[]) line: 219

      Thread [main] (Suspended (breakpoint at line 42 in de.compeople.spirit.communication.base.microkernel.objectprovider.WebServiceObjectProvider))
      de.compeople.spirit.communication.base.microkernel.objectprovider.WebServiceObjectProvider.provideObject(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: 42
      $ObjectProvider_1027bec98d3.provideObject(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: not available
      $ObjectProvider_1027bec98d2.provideObject(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: not available
      org.apache.hivemind.service.impl.ObjectTranslator.translate(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: 75
      $Translator_1027bec98c2.translate(org.apache.hivemind.internal.Module, java.lang.Class, java.lang.String, org.apache.hivemind.Location) line: not available
      org.apache.hivemind.service.impl.BuilderPropertyFacet.getFacetValue(org.apache.hivemind.ServiceImplementationFactoryParameters, java.lang.Class) line: 41
      org.apache.hivemind.service.impl.BuilderPropertyFacet.isAssignableToType(org.apache.hivemind.ServiceImplementationFactoryParameters, java.lang.Class) line: 54
      org.apache.hivemind.service.impl.BuilderFactoryLogic.instantiateExplicitConstructorInstance(java.lang.Class, java.util.List) line: 132
      ===========
      org.apache.hivemind.service.impl.BuilderFactoryLogic.instantiateCoreServiceInstance() line: 112
      org.apache.hivemind.service.impl.BuilderFactoryLogic.createService() line: 77
      org.apache.hivemind.service.impl.BuilderFactory.createCoreServiceImplementation(org.apache.hivemind.ServiceImplementationFactoryParameters) line: 42
      org.apache.hivemind.impl.InvokeFactoryServiceConstructor.constructCoreServiceImplementation() line: 84
      org.apache.hivemind.impl.servicemodel.SingletonServiceModel(org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl).constructCoreServiceImplementation() line: 106
      org.apache.hivemind.impl.servicemodel.SingletonServiceModel(org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl).constructNewServiceImplementation() line: 156
      org.apache.hivemind.impl.servicemodel.SingletonServiceModel(org.apache.hivemind.impl.servicemodel.AbstractServiceModelImpl).constructServiceImplementation() line: 138
      org.apache.hivemind.impl.servicemodel.SingletonServiceModel.getActualServiceImplementation() line: 68
      $IPingHolder_1027bec98eb._service() line: not available
      $IPingHolder_1027bec98eb.getPing() line: not available
      $IPingHolder_1027bec98ea.getPing() line: not available
      de.compeople.spirit.communication.base.mikrokernel.objectprovider.WebServiceObjectProviderUsageTest.testBuildWebServiceWithoutTimeoutAndConstructorInjection() line: 39
      sun.reflect.NativeMethodAccessorImpl.invoke0(java.lang.reflect.Method, java.lang.Object, java.lang.Object[]) line: not available [native method]
      sun.reflect.NativeMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 39
      sun.reflect.DelegatingMethodAccessorImpl.invoke(java.lang.Object, java.lang.Object[]) line: 25
      java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object...) line: 585
      de.compeople.spirit.communication.base.mikrokernel.objectprovider.WebServiceObjectProviderUsageTest(junit.framework.TestCase).runTest() line: 154
      de.compeople.spirit.communication.base.mikrokernel.objectprovider.WebServiceObjectProviderUsageTest(junit.framework.TestCase).runBare() line: 127
      junit.framework.TestResult$1.protect() line: 106
      junit.framework.TestResult.runProtected(junit.framework.Test, junit.framework.Protectable) line: 124
      junit.framework.TestResult.run(junit.framework.TestCase) line: 109
      de.compeople.spirit.communication.base.mikrokernel.objectprovider.WebServiceObjectProviderUsageTest(junit.framework.TestCase).run(junit.framework.TestResult) line: 118
      org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(java.lang.String[], java.lang.String) line: 598
      org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run() line: 354
      org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(java.lang.String[]) line: 219

      As you can see the object provider is reached from two different points within BuilderFactoryLogic.instantiateExplicitConstructorInstance at line 132 and line 135 (marked with ===== in the stacktraces). Everything ´before´ is the same.

      Achim Huegen commented this:
      The reason is that BuilderFactoryLogic checks the provider value
      for compliance with the constructor parameter type, before assigning
      the value. For this check the current value is retrieved from the
      provider and after the check the value is retrieved again for assignment.

      That could be prevented by introducing some caching in
      BuilderPropertyFacet, but I'm not quite sure how this contradicts
      the dynamic nature of an object provider (that is the value could change
      over time).
      Hmmmhhh ... thinking longer about this I would even say it is quite
      dangerous not to cache the retrieved value.
      If the value changes during the construction process of a single
      service, the BuilderFactory will work with inconsistent data.
      Moreover the getFacetValue method is called quite often if multiple
      constructor candidates exists.

      Attachments

        Activity

          People

            Unassigned Unassigned
            stefan liebig Stefan Liebig
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: