Frage

Ich habe mein System in zwei Teile unterteilt.Beide Teile kommunizieren miteinander andere mit Rhino Service Bus. Unter Windows 7 gibt es kein Problem, aber wenn ich es irgendwo anders starte (WinXP, Server 2003, ...) Ich erhalte die folgende Ausnahme wenn ich Rhino.ServiceBus.Hosting.DefaultHost.Start(..) aufrufe:

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)

Hier ist das Fragment aus dem Spring-Protokoll:

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

War es hilfreich?

Lösung

Problem gelöst: In MSMQ Version 3 oder niedriger (auf Systemen wie Windows XP, Windows Server 2003) werden Unterwarteschlangen nicht unterstützt. Daher verwendet Rhino SB FlatQueueStrategy zum Verwalten der Warteschlangen. Probleme treten auf, wenn der Spring-Objektcontainer konfiguriert ist. Konkret gibt es in der Klasse Rhino.ServiceBus.Spring.SpringBuilder zwei Stellen, an denen Änderungen vorgenommen werden müssen.

1) Methode RegisterMsmqTransport :

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);
}

Der zweite Teil der if-Anweisung wird immer aufgerufen, da FlatQueueStrategy keinen Konstruktor mit Parametern vom Typ IQueueStrategy und Uri hat. Aber es gibt nicht einmal den Konstruktor ohne Parameter. FlatQueueStrategy ist daher im Objektcontainer nicht korrekt registriert. Die Änderung für diesen Teil wäre:

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) Methode RegisterDefaultServices

Das nächste Problem liegt in der Methode 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());

Die Methode RegisterMsmqTransport wird aufgerufen, bevor IEndpointRouter im Objektcontainer registriert wird. IEndpointRouter wird in der Methode RegisterMsmqTransport (siehe 1) und daher im Methodenaufruf verwendet

    applicationContext.Get<IEndpointRouter>()

erzeugt eine Ausnahme. Die Änderung hier wäre:

    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);

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top