Question

J'ai mon système divisé en 2 parties. Les deux pièces communiquent entre elles à l'aide d'un bus de service Rhino. Il n'y a pas de problème sur Windows 7, mais si je le démarre ailleurs (WinXP, Server 2003, ...), j'obtiens l'exception suivante lorsque j'appelle Rhino.ServiceBus.Hosting.DefaultHost.Start(..):

System.NullReferenceException: Object reference not set to an instance of an object.
   at Spring.Objects.Factory.Support.AbstractObjectFactory.GetObjectFromFactoryObject(IFactoryObject factory, String objectName, RootObjectDefinition rod)
   at Spring.Objects.Factory.Support.AbstractObjectFactory.GetObjectForInstance(Object instance, String name, String canonicalName, RootObjectDefinition rod)
   at Spring.Objects.Factory.Support.AbstractObjectFactory.GetObjectInternal(String name, Type requiredType, Object[] arguments, Boolean suppressConfigure)
   at Spring.Objects.Factory.Support.AbstractObjectFactory.GetObject(String name)
   at Spring.Context.Support.AbstractApplicationContext.GetObject(String name)
   at Rhino.ServiceBus.Spring.ApplicationContextExtensions.Get(IApplicationContext context, Type type)
   at Rhino.ServiceBus.Spring.ApplicationContextExtensions.Get[T](IConfigurableApplicationContext context)
   at Rhino.ServiceBus.Spring.SpringBootStrapper.GetInstance[T]()
   at Rhino.ServiceBus.Hosting.DefaultHost.InitailizeBus(String asmName)
   at Rhino.ServiceBus.Hosting.DefaultHost.Start(String asmName)

Voici le journal de printemps du formulaire de fragment:

2012-01-14 13:25:01,084 DEBUG Spring.Objects.Factory.Support.DefaultListableObjectFactory - Invoking IObjectPostProcessors after initialization of object '351a5f07-e33d-4be0-84cf-1738a8feba24'
2012-01-14 13:25:01,084 DEBUG Spring.Objects.Factory.Support.DefaultListableObjectFactory -          GetObjectInternal: returning instance for objectname 351a5f07-e33d-4be0-84cf-1738a8feba24
2012-01-14 13:25:01,084 ERROR Spring.Objects.Factory.Support.DefaultListableObjectFactory -       GetObjectInternal: error obtaining object Rhino.ServiceBus.Msmq.FlatQueueStrategy
2012-01-14 13:25:01,084 ERROR Spring.Objects.Factory.Support.DefaultListableObjectFactory -    GetObjectInternal: error obtaining object Rhino.ServiceBus.Msmq.MsmqTransport
2012-01-14 13:25:01,084 ERROR Spring.Objects.Factory.Support.DefaultListableObjectFactory - GetObjectInternal: error obtaining object 1a769f24-5410-4cee-8d7a-76c3a91b1ce1
Était-ce utile?

La solution

Problème résolu: dans la version 3 MSMQ ou plus bas (sur des systèmes comme Windows XP, Windows Server 2003), les sous-questions ne sont pas prises en charge et donc Rhino SB utilise Flatqueuestrategy pour gérer les files d'attente. Les problèmes se produisent lorsque le conteneur d'objet Spring est configuré. Concrètement, il y a deux endroits dans la classe Rhino.ServiceBus.spring.springBuilder où les modifications doivent être effectuées.

1) Méthode Registremqtransport:

if (queueStrategyType.GetConstructor(new[] { typeof(IQueueStrategy), typeof(Uri) }) != null)
{
    applicationContext.RegisterSingleton(queueStrategyType, typeof (IQueueStrategy).FullName, applicationContext.Get<IEndpointRouter>(), config.Endpoint);
}
else
{
    // use default
    applicationContext.RegisterSingleton(queueStrategyType);
}

La deuxième partie de l'instruction IF est toujours appelée, car Flatqueuestrategy n'a pas de constructeur avec des paramètres de type iqueuestrategy et uri. Mais il n'a même pas le constructeur sans paramètres. Donc, Flatqueuestrategy n'est pas enregistré correctement dans le conteneur d'objet. La modification de cette partie serait:

if (queueStrategyType.GetConstructor(new[] { typeof(IEndpointRouter), typeof(Uri) }) != null)
{
    applicationContext.RegisterSingleton(queueStrategyType, typeof (IQueueStrategy).FullName, applicationContext.Get<IEndpointRouter>(), config.Endpoint);
}
else
{
    // use default
    applicationContext.RegisterSingleton(queueStrategyType);
}

2) Méthode Registre desservices

Le problème suivant réside dans la méthode RegisterDefaultServices:

    applicationContext.RegisterSingleton<IServiceLocator>(() => new SpringServiceLocator(applicationContext));
    applicationContext.RegisterSingletons<IBusConfigurationAware>(typeof(IServiceBus).Assembly);

    foreach (var busConfigurationAware in applicationContext.GetAll<IBusConfigurationAware>())
    {
        busConfigurationAware.Configure(config, this);  // here is the method RegisterMsmqTransport called
    }

    foreach (var module in config.MessageModules)
    {
        applicationContext.RegisterSingleton(module, module.FullName);
    }

    applicationContext.RegisterSingleton<IReflection>(() => new DefaultReflection());
    applicationContext.RegisterSingleton(config.SerializerType);
    applicationContext.RegisterSingleton<IEndpointRouter>(() => new EndpointRouter());

La méthode registremsmqtransport est appelée avant que iendpointrouter ne soit enregistré dans le conteneur d'objets. Iendpointrouter est utilisé dans la méthode registremsmqtransport (voir 1) et donc l'appel de la méthode

    applicationContext.Get<IEndpointRouter>()

produit une exception. La modification ici serait:

    applicationContext.RegisterSingleton<IServiceLocator>(() => new SpringServiceLocator(applicationContext));
    applicationContext.RegisterSingletons<IBusConfigurationAware>(typeof(IServiceBus).Assembly);
    applicationContext.RegisterSingleton<IReflection>(() => new DefaultReflection());
    applicationContext.RegisterSingleton<IEndpointRouter>(() => new EndpointRouter());

    foreach (var busConfigurationAware in applicationContext.GetAll<IBusConfigurationAware>())
    {
        busConfigurationAware.Configure(config, this);
    }

    foreach (var module in config.MessageModules)
    {
        applicationContext.RegisterSingleton(module, module.FullName);
    }

    applicationContext.RegisterSingleton(config.SerializerType);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top