.NET Forum / .NET Framework / Component Services / September 2004
can not deserilaize the remote interface returned from a Factory hosting ServicedComponent : " Insufficient state to deserialize the object."
|
|
Thread rating:  |
Jim Hsu - 13 Sep 2004 14:40 GMT I use a remote factory to dynamic load the .net servicedComponent , and return as an fixed interface.
it does not work. , the error below, , the funny thing is that when I add reference to this .net servicedcomponent in the client, it will work, however, apparently this break the idea of "dynamic".
the same code work perfectly for a component inheritant from MarshalByRefObject in stead., so it seems the code is ok, just does not work with serviced component.
I pasted to code below: can anyone tell what is going wrong. If I am going on the wrong direction, let me know, I need COM+ for object pooling, application recycling, statistics ...etc. I don't like to build thing from the scratch, the truth that MS is hold us to wait for Indigo in 2+ years, is not a good news for us building enterprise application .net application ... sigh..., just $.02
"Event Type: Error Event Source: Sharkgrin.tigerCon Event Category: (78) Event ID: 888 Date: 9/13/2004 Time: 9:25:54 PM User: N/A Computer: LUNAR1 Description: con error ----------------LogPack Statck Trace ------------------- Error at offset 137 in file:line:column d:\j\depot\bluestar\integration\main\instrumentations\logpack\logpack.cs:756:6 CheethasCon3 at offset 314 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:235:5 Main at offset 13 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:41:4
System.Runtime.Serialization.SerializationException: Insufficient state to deserialize the object. More information is needed.
Server stack trace: at System.UnitySerializationHolder.GetRealObject(StreamingContext context) at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder) at System.Runtime.Serialization.ObjectManager.DoFixups() at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeMessageParts(MemoryStream stm) at System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage.FixupForNewAppDomain() at System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage reqMsg)
Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Sharkgrin.RemoteFactory.LoadAdapter(String assemblyFile, String typeName, Object[] constructArgs) in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\remotefactory.cs:line 27 at Sharkgrin.tigerCon.CheethasCon3() in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:line 226
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp. "
source code
public static void conDoe4()
{
Console.WriteLine("ConDoe4() in use!");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = doeFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
setup.ApplicationName = "AdapterDoeLoader";
//AppDomain appDomain1 = "DoeLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
a1 = factory1.LoadAdapter("Doe", "Sharkgrin.Doe", null);
logger.Debug("doe loaded!");
logger.Info("Doe.SendReceive(1234abcd) = " + a1.SendReceive("1234abcd"));
}
public static void CheethasCon3()
{
logger.Debug(" CheethasCon 3 : using AppDomain RemoteLoader !");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = adapterFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
//setup.PrivateBinPath = adapterFolder;
setup.ApplicationName = "AdapterLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
try
{
a1 = factory1.LoadAdapter("cheethasJr",
"BlueStar.Integration.Adapters.CheethasJr",null);
logger.Debug( "or1 returned ");
}
catch(Exception e)
{
logger.Error("con error", e, 888);
Thread.Sleep(77000);
}
if (a1 == null)
{
logger.Error("a1 is null",888);
}
else
{
logger.Info(" as.sendReceive " + a1.SendReceive("1234abced, from remote a.."));
}
}
public class RemoteFactory : MarshalByRefObject
{
static readonly LogPack logger LogPack.GetLogger(typeof(RemoteFactory));
private const BindingFlags bfi =
BindingFlags.Instance | BindingFlags.Public |
BindingFlags.CreateInstance ;
public IAdapter LoadAdapter( string assemblyFile,
string typeName,object[] constructArgs )
{
logger.Debug("Create() -> tassemblyFile : " + assemblyFile +
"typeName = " + typeName);
logger.Debug("AppDomain Base : " + AppDomain.CurrentDomain.BaseDirectory );
logger.Debug("Appdomain FreindlyName = " + AppDomain.CurrentDomain.FriendlyName);
logger.Info( "\tRelativeSearchPath : " + AppDomain.CurrentDomain.RelativeSearchPath);
logger.Info("\tPrivateBinPath : " + AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
logger.Debug("assembly loading ...!");
Assembly ass1 = Assembly.Load(assemblyFile);
if (ass1 == null)
{
logger.Error(" ass1 is null ", 888);
}
else
{
logger.Debug(" ass1 is not null !" );
}
object o1 = ass1.CreateInstance( typeName);
// ObjectHandle oh1 = .CreateInstanceFrom( assemblyFile,
// typeName,false, bfi, null, constructArgs,null,null,null);
//
// object o1 = oh1.Unwrap();
if (o1!= null)
{
logger.Debug("o1 is not null!");
}
else
{
logger.Error("o1 is null ", 88);
}
// MarshalByRefObject mbro1 = null;
// mbro1 = o1 as MarshalByRefObject;
// if (mbro1!= null)
// {
// logger.Debug("Mbro1 is not null!");
// }
// else
// {
// logger.Error("Mbro1 is null ", 88);
//
// }
// return RemotingServices.Marshal(mbro1);
IAdapter a1 = o1 as IAdapter;
if ( a1 == null )
{
logger.Error(" as is null !", 88);
return null;
}
else
{
logger.Debug(" o1 as a1 will be returned !");
return a1;
}
}
José Miguel Torres - 13 Sep 2004 15:12 GMT Hi Jim, have you registered your COM+ application as Library o Server application? regards
 Signature José Miguel Torres jtorres_diaz~~ARROBA~~terra.es http://jmtorres.blogspot.com
I use a remote factory to dynamic load the .net servicedComponent , and return as an fixed interface.
it does not work. , the error below, , the funny thing is that when I add reference to this .net servicedcomponent in the client, it will work, however, apparently this break the idea of "dynamic".
the same code work perfectly for a component inheritant from MarshalByRefObject in stead., so it seems the code is ok, just does not work with serviced component.
I pasted to code below: can anyone tell what is going wrong. If I am going on the wrong direction, let me know, I need COM+ for object pooling, application recycling, statistics ...etc. I don't like to build thing from the scratch, the truth that MS is hold us to wait for Indigo in 2+ years, is not a good news for us building enterprise application .net application ... sigh..., just $.02
"Event Type: Error Event Source: Sharkgrin.tigerCon Event Category: (78) Event ID: 888 Date: 9/13/2004 Time: 9:25:54 PM User: N/A Computer: LUNAR1 Description: con error ----------------LogPack Statck Trace ------------------- Error at offset 137 in file:line:column d:\j\depot\bluestar\integration\main\instrumentations\logpack\logpack.cs:756:6 CheethasCon3 at offset 314 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:235:5 Main at offset 13 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:41:4
System.Runtime.Serialization.SerializationException: Insufficient state to deserialize the object. More information is needed.
Server stack trace: at System.UnitySerializationHolder.GetRealObject(StreamingContext context) at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder) at System.Runtime.Serialization.ObjectManager.DoFixups() at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeMessageParts(MemoryStream stm) at System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage.FixupForNewAppDomain() at System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage reqMsg)
Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Sharkgrin.RemoteFactory.LoadAdapter(String assemblyFile, String typeName, Object[] constructArgs) in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\remotefactory.cs:line 27 at Sharkgrin.tigerCon.CheethasCon3() in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:line 226
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp. "
source code
public static void conDoe4()
{
Console.WriteLine("ConDoe4() in use!");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = doeFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
setup.ApplicationName = "AdapterDoeLoader";
//AppDomain appDomain1 = "DoeLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
a1 = factory1.LoadAdapter("Doe", "Sharkgrin.Doe", null);
logger.Debug("doe loaded!");
logger.Info("Doe.SendReceive(1234abcd) = " + a1.SendReceive("1234abcd"));
}
public static void CheethasCon3()
{
logger.Debug(" CheethasCon 3 : using AppDomain RemoteLoader !");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = adapterFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
//setup.PrivateBinPath = adapterFolder;
setup.ApplicationName = "AdapterLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
try
{
a1 = factory1.LoadAdapter("cheethasJr",
"BlueStar.Integration.Adapters.CheethasJr",null);
logger.Debug( "or1 returned ");
}
catch(Exception e)
{
logger.Error("con error", e, 888);
Thread.Sleep(77000);
}
if (a1 == null)
{
logger.Error("a1 is null",888);
}
else
{
logger.Info(" as.sendReceive " + a1.SendReceive("1234abced, from remote a.."));
}
}
public class RemoteFactory : MarshalByRefObject
{
static readonly LogPack logger LogPack.GetLogger(typeof(RemoteFactory));
private const BindingFlags bfi =
BindingFlags.Instance | BindingFlags.Public |
BindingFlags.CreateInstance ;
public IAdapter LoadAdapter( string assemblyFile,
string typeName,object[] constructArgs )
{
logger.Debug("Create() -> tassemblyFile : " + assemblyFile +
"typeName = " + typeName);
logger.Debug("AppDomain Base : " + AppDomain.CurrentDomain.BaseDirectory );
logger.Debug("Appdomain FreindlyName = " + AppDomain.CurrentDomain.FriendlyName);
logger.Info( "\tRelativeSearchPath : " + AppDomain.CurrentDomain.RelativeSearchPath);
logger.Info("\tPrivateBinPath : " + AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
logger.Debug("assembly loading ...!");
Assembly ass1 = Assembly.Load(assemblyFile);
if (ass1 == null)
{
logger.Error(" ass1 is null ", 888);
}
else
{
logger.Debug(" ass1 is not null !" );
}
object o1 = ass1.CreateInstance( typeName);
// ObjectHandle oh1 = .CreateInstanceFrom( assemblyFile,
// typeName,false, bfi, null, constructArgs,null,null,null);
//
// object o1 = oh1.Unwrap();
if (o1!= null)
{
logger.Debug("o1 is not null!");
}
else
{
logger.Error("o1 is null ", 88);
}
// MarshalByRefObject mbro1 = null;
// mbro1 = o1 as MarshalByRefObject;
// if (mbro1!= null)
// {
// logger.Debug("Mbro1 is not null!");
// }
// else
// {
// logger.Error("Mbro1 is null ", 88);
//
// }
// return RemotingServices.Marshal(mbro1);
IAdapter a1 = o1 as IAdapter;
if ( a1 == null )
{
logger.Error(" as is null !", 88);
return null;
}
else
{
logger.Debug(" o1 as a1 will be returned !");
return a1;
}
}
Jim Hsu - 13 Sep 2004 17:45 GMT Jose: yes, I have, both server and library will not work in fact, the loader can load the .net assembly w/o issues, the problem is when the remote loader return the instanced casted to interface ( IAdapter in my case ). in the default domain, there is an error stating that "System.Runtime.Serialization.SerializationException: Insufficient state to deserialize the object. More information is needed." in the line :
" a1 = factory1.LoadAdapter("cheethasJr",
"BlueStar.Integration.Adapters.CheethasJr",null);
"
and the interesting things is when I add reference to the target assembly ( which should be dynamically loaded ). the error is gone. however, it makes not sense to reference the assembly which are to be loaded in run time.
this issue does not repro if the to be loaded type is marshalByRefObject instead of servicedComponent.
Hi Jim, have you registered your COM+ application as Library o Server application? regards
-- José Miguel Torres jtorres_diaz~~ARROBA~~terra.es http://jmtorres.blogspot.com "Jim Hsu" <orice.bug@nospam.msa.hinet.net> escribió en el mensaje news:erCLtcZmEHA.3428@TK2MSFTNGP14.phx.gbl... I use a remote factory to dynamic load the .net servicedComponent , and return as an fixed interface.
it does not work. , the error below, , the funny thing is that when I add reference to this .net servicedcomponent in the client, it will work, however, apparently this break the idea of "dynamic".
the same code work perfectly for a component inheritant from MarshalByRefObject in stead., so it seems the code is ok, just does not work with serviced component.
I pasted to code below: can anyone tell what is going wrong. If I am going on the wrong direction, let me know, I need COM+ for object pooling, application recycling, statistics ...etc. I don't like to build thing from the scratch, the truth that MS is hold us to wait for Indigo in 2+ years, is not a good news for us building enterprise application .net application ... sigh..., just $.02
"Event Type: Error Event Source: Sharkgrin.tigerCon Event Category: (78) Event ID: 888 Date: 9/13/2004 Time: 9:25:54 PM User: N/A Computer: LUNAR1 Description: con error ----------------LogPack Statck Trace ------------------- Error at offset 137 in file:line:column d:\j\depot\bluestar\integration\main\instrumentations\logpack\logpack.cs:756:6 CheethasCon3 at offset 314 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:235:5 Main at offset 13 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:41:4
System.Runtime.Serialization.SerializationException: Insufficient state to deserialize the object. More information is needed.
Server stack trace: at System.UnitySerializationHolder.GetRealObject(StreamingContext context) at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder) at System.Runtime.Serialization.ObjectManager.DoFixups() at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeMessageParts(MemoryStream stm) at System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage.FixupForNewAppDomain() at System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage reqMsg)
Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Sharkgrin.RemoteFactory.LoadAdapter(String assemblyFile, String typeName, Object[] constructArgs) in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\remotefactory.cs:line 27 at Sharkgrin.tigerCon.CheethasCon3() in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:line 226
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp. "
source code
public static void conDoe4()
{
Console.WriteLine("ConDoe4() in use!");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = doeFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
setup.ApplicationName = "AdapterDoeLoader";
//AppDomain appDomain1 = "DoeLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
a1 = factory1.LoadAdapter("Doe", "Sharkgrin.Doe", null);
logger.Debug("doe loaded!");
logger.Info("Doe.SendReceive(1234abcd) = " + a1.SendReceive("1234abcd"));
}
public static void CheethasCon3()
{
logger.Debug(" CheethasCon 3 : using AppDomain RemoteLoader !");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = adapterFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
//setup.PrivateBinPath = adapterFolder;
setup.ApplicationName = "AdapterLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
try
{
a1 = factory1.LoadAdapter("cheethasJr",
"BlueStar.Integration.Adapters.CheethasJr",null);
logger.Debug( "or1 returned ");
}
catch(Exception e)
{
logger.Error("con error", e, 888);
Thread.Sleep(77000);
}
if (a1 == null)
{
logger.Error("a1 is null",888);
}
else
{
logger.Info(" as.sendReceive " + a1.SendReceive("1234abced, from remote a.."));
}
}
public class RemoteFactory : MarshalByRefObject
{
static readonly LogPack logger LogPack.GetLogger(typeof(RemoteFactory));
private const BindingFlags bfi =
BindingFlags.Instance | BindingFlags.Public |
BindingFlags.CreateInstance ;
public IAdapter LoadAdapter( string assemblyFile,
string typeName,object[] constructArgs )
{
logger.Debug("Create() -> tassemblyFile : " + assemblyFile +
"typeName = " + typeName);
logger.Debug("AppDomain Base : " + AppDomain.CurrentDomain.BaseDirectory );
logger.Debug("Appdomain FreindlyName = " + AppDomain.CurrentDomain.FriendlyName);
logger.Info( "\tRelativeSearchPath : " + AppDomain.CurrentDomain.RelativeSearchPath);
logger.Info("\tPrivateBinPath : " + AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
logger.Debug("assembly loading ...!");
Assembly ass1 = Assembly.Load(assemblyFile);
if (ass1 == null)
{
logger.Error(" ass1 is null ", 888);
}
else
{
logger.Debug(" ass1 is not null !" );
}
object o1 = ass1.CreateInstance( typeName);
// ObjectHandle oh1 = .CreateInstanceFrom( assemblyFile,
// typeName,false, bfi, null, constructArgs,null,null,null);
//
// object o1 = oh1.Unwrap();
if (o1!= null)
{
logger.Debug("o1 is not null!");
}
else
{
logger.Error("o1 is null ", 88);
}
// MarshalByRefObject mbro1 = null;
// mbro1 = o1 as MarshalByRefObject;
// if (mbro1!= null)
// {
// logger.Debug("Mbro1 is not null!");
// }
// else
// {
// logger.Error("Mbro1 is null ", 88);
//
// }
// return RemotingServices.Marshal(mbro1);
IAdapter a1 = o1 as IAdapter;
if ( a1 == null )
{
logger.Error(" as is null !", 88);
return null;
}
else
{
logger.Debug(" o1 as a1 will be returned !");
return a1;
}
}
Jim Hsu - 14 Sep 2004 05:45 GMT I am in the dead water now, I tried to work around this using AssemblyLoadFrom, but I 've no activator to activate and process the return ObjectHandle from the ServicedComponent....
can anyone shed some lights on this?
otherwise, I have to build a poolman's COM+ using C#....
sigh...
Jose: yes, I have, both server and library will not work in fact, the loader can load the .net assembly w/o issues, the problem is when the remote loader return the instanced casted to interface ( IAdapter in my case ). in the default domain, there is an error stating that "System.Runtime.Serialization.SerializationException: Insufficient state to deserialize the object. More information is needed." in the line :
" a1 = factory1.LoadAdapter("cheethasJr",
"BlueStar.Integration.Adapters.CheethasJr",null);
"
and the interesting things is when I add reference to the target assembly ( which should be dynamically loaded ). the error is gone. however, it makes not sense to reference the assembly which are to be loaded in run time.
this issue does not repro if the to be loaded type is marshalByRefObject instead of servicedComponent.
"José Miguel Torres" <jtorres_diaz~~ARROBA~~terra.es> wrote in message news:ObDV%23uZmEHA.1376@TK2MSFTNGP12.phx.gbl... Hi Jim, have you registered your COM+ application as Library o Server application? regards
-- José Miguel Torres jtorres_diaz~~ARROBA~~terra.es http://jmtorres.blogspot.com "Jim Hsu" <orice.bug@nospam.msa.hinet.net> escribió en el mensaje news:erCLtcZmEHA.3428@TK2MSFTNGP14.phx.gbl... I use a remote factory to dynamic load the .net servicedComponent , and return as an fixed interface.
it does not work. , the error below, , the funny thing is that when I add reference to this .net servicedcomponent in the client, it will work, however, apparently this break the idea of "dynamic".
the same code work perfectly for a component inheritant from MarshalByRefObject in stead., so it seems the code is ok, just does not work with serviced component.
I pasted to code below: can anyone tell what is going wrong. If I am going on the wrong direction, let me know, I need COM+ for object pooling, application recycling, statistics ...etc. I don't like to build thing from the scratch, the truth that MS is hold us to wait for Indigo in 2+ years, is not a good news for us building enterprise application .net application ... sigh..., just $.02
"Event Type: Error Event Source: Sharkgrin.tigerCon Event Category: (78) Event ID: 888 Date: 9/13/2004 Time: 9:25:54 PM User: N/A Computer: LUNAR1 Description: con error ----------------LogPack Statck Trace ------------------- Error at offset 137 in file:line:column d:\j\depot\bluestar\integration\main\instrumentations\logpack\logpack.cs:756:6 CheethasCon3 at offset 314 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:235:5 Main at offset 13 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:41:4
System.Runtime.Serialization.SerializationException: Insufficient state to deserialize the object. More information is needed.
Server stack trace: at System.UnitySerializationHolder.GetRealObject(StreamingContext context) at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder) at System.Runtime.Serialization.ObjectManager.DoFixups() at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeMessageParts(MemoryStream stm) at System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage.FixupForNewAppDomain() at System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage reqMsg)
Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Sharkgrin.RemoteFactory.LoadAdapter(String assemblyFile, String typeName, Object[] constructArgs) in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\remotefactory.cs:line 27 at Sharkgrin.tigerCon.CheethasCon3() in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:line 226
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp. "
source code
public static void conDoe4()
{
Console.WriteLine("ConDoe4() in use!");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = doeFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
setup.ApplicationName = "AdapterDoeLoader";
//AppDomain appDomain1 = "DoeLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
a1 = factory1.LoadAdapter("Doe", "Sharkgrin.Doe", null);
logger.Debug("doe loaded!");
logger.Info("Doe.SendReceive(1234abcd) = " + a1.SendReceive("1234abcd"));
}
public static void CheethasCon3()
{
logger.Debug(" CheethasCon 3 : using AppDomain RemoteLoader !");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = adapterFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
//setup.PrivateBinPath = adapterFolder;
setup.ApplicationName = "AdapterLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
try
{
a1 = factory1.LoadAdapter("cheethasJr",
"BlueStar.Integration.Adapters.CheethasJr",null);
logger.Debug( "or1 returned ");
}
catch(Exception e)
{
logger.Error("con error", e, 888);
Thread.Sleep(77000);
}
if (a1 == null)
{
logger.Error("a1 is null",888);
}
else
{
logger.Info(" as.sendReceive " + a1.SendReceive("1234abced, from remote a.."));
}
}
public class RemoteFactory : MarshalByRefObject
{
static readonly LogPack logger LogPack.GetLogger(typeof(RemoteFactory));
private const BindingFlags bfi =
BindingFlags.Instance | BindingFlags.Public |
BindingFlags.CreateInstance ;
public IAdapter LoadAdapter( string assemblyFile,
string typeName,object[] constructArgs )
{
logger.Debug("Create() -> tassemblyFile : " + assemblyFile +
"typeName = " + typeName);
logger.Debug("AppDomain Base : " + AppDomain.CurrentDomain.BaseDirectory );
logger.Debug("Appdomain FreindlyName = " + AppDomain.CurrentDomain.FriendlyName);
logger.Info( "\tRelativeSearchPath : " + AppDomain.CurrentDomain.RelativeSearchPath);
logger.Info("\tPrivateBinPath : " + AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
logger.Debug("assembly loading ...!");
Assembly ass1 = Assembly.Load(assemblyFile);
if (ass1 == null)
{
logger.Error(" ass1 is null ", 888);
}
else
{
logger.Debug(" ass1 is not null !" );
}
object o1 = ass1.CreateInstance( typeName);
// ObjectHandle oh1 = .CreateInstanceFrom( assemblyFile,
// typeName,false, bfi, null, constructArgs,null,null,null);
//
// object o1 = oh1.Unwrap();
if (o1!= null)
{
logger.Debug("o1 is not null!");
}
else
{
logger.Error("o1 is null ", 88);
}
// MarshalByRefObject mbro1 = null;
// mbro1 = o1 as MarshalByRefObject;
// if (mbro1!= null)
// {
// logger.Debug("Mbro1 is not null!");
// }
// else
// {
// logger.Error("Mbro1 is null ", 88);
//
// }
// return RemotingServices.Marshal(mbro1);
IAdapter a1 = o1 as IAdapter;
if ( a1 == null )
{
logger.Error(" as is null !", 88);
return null;
}
else
{
logger.Debug(" o1 as a1 will be returned !");
return a1;
}
}
José Miguel Torres - 14 Sep 2004 09:34 GMT Hi Jim,
Now make sure to put the assembly into GAC, tell me as it goes... regards
 Signature José Miguel Torres jtorres_diaz~~ARROBA~~terra.es http://jmtorres.blogspot.com
I use a remote factory to dynamic load the .net servicedComponent , and return as an fixed interface.
it does not work. , the error below, , the funny thing is that when I add reference to this .net servicedcomponent in the client, it will work, however, apparently this break the idea of "dynamic".
the same code work perfectly for a component inheritant from MarshalByRefObject in stead., so it seems the code is ok, just does not work with serviced component.
I pasted to code below: can anyone tell what is going wrong. If I am going on the wrong direction, let me know, I need COM+ for object pooling, application recycling, statistics ...etc. I don't like to build thing from the scratch, the truth that MS is hold us to wait for Indigo in 2+ years, is not a good news for us building enterprise application .net application ... sigh..., just $.02
"Event Type: Error Event Source: Sharkgrin.tigerCon Event Category: (78) Event ID: 888 Date: 9/13/2004 Time: 9:25:54 PM User: N/A Computer: LUNAR1 Description: con error ----------------LogPack Statck Trace ------------------- Error at offset 137 in file:line:column d:\j\depot\bluestar\integration\main\instrumentations\logpack\logpack.cs:756:6 CheethasCon3 at offset 314 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:235:5 Main at offset 13 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:41:4
System.Runtime.Serialization.SerializationException: Insufficient state to deserialize the object. More information is needed.
Server stack trace: at System.UnitySerializationHolder.GetRealObject(StreamingContext context) at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder) at System.Runtime.Serialization.ObjectManager.DoFixups() at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeMessageParts(MemoryStream stm) at System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage.FixupForNewAppDomain() at System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage reqMsg)
Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Sharkgrin.RemoteFactory.LoadAdapter(String assemblyFile, String typeName, Object[] constructArgs) in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\remotefactory.cs:line 27 at Sharkgrin.tigerCon.CheethasCon3() in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:line 226
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp. "
source code
public static void conDoe4()
{
Console.WriteLine("ConDoe4() in use!");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = doeFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
setup.ApplicationName = "AdapterDoeLoader";
//AppDomain appDomain1 = "DoeLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
a1 = factory1.LoadAdapter("Doe", "Sharkgrin.Doe", null);
logger.Debug("doe loaded!");
logger.Info("Doe.SendReceive(1234abcd) = " + a1.SendReceive("1234abcd"));
}
public static void CheethasCon3()
{
logger.Debug(" CheethasCon 3 : using AppDomain RemoteLoader !");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = adapterFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
//setup.PrivateBinPath = adapterFolder;
setup.ApplicationName = "AdapterLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
try
{
a1 = factory1.LoadAdapter("cheethasJr",
"BlueStar.Integration.Adapters.CheethasJr",null);
logger.Debug( "or1 returned ");
}
catch(Exception e)
{
logger.Error("con error", e, 888);
Thread.Sleep(77000);
}
if (a1 == null)
{
logger.Error("a1 is null",888);
}
else
{
logger.Info(" as.sendReceive " + a1.SendReceive("1234abced, from remote a.."));
}
}
public class RemoteFactory : MarshalByRefObject
{
static readonly LogPack logger LogPack.GetLogger(typeof(RemoteFactory));
private const BindingFlags bfi =
BindingFlags.Instance | BindingFlags.Public |
BindingFlags.CreateInstance ;
public IAdapter LoadAdapter( string assemblyFile,
string typeName,object[] constructArgs )
{
logger.Debug("Create() -> tassemblyFile : " + assemblyFile +
"typeName = " + typeName);
logger.Debug("AppDomain Base : " + AppDomain.CurrentDomain.BaseDirectory );
logger.Debug("Appdomain FreindlyName = " + AppDomain.CurrentDomain.FriendlyName);
logger.Info( "\tRelativeSearchPath : " + AppDomain.CurrentDomain.RelativeSearchPath);
logger.Info("\tPrivateBinPath : " + AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
logger.Debug("assembly loading ...!");
Assembly ass1 = Assembly.Load(assemblyFile);
if (ass1 == null)
{
logger.Error(" ass1 is null ", 888);
}
else
{
logger.Debug(" ass1 is not null !" );
}
object o1 = ass1.CreateInstance( typeName);
// ObjectHandle oh1 = .CreateInstanceFrom( assemblyFile,
// typeName,false, bfi, null, constructArgs,null,null,null);
//
// object o1 = oh1.Unwrap();
if (o1!= null)
{
logger.Debug("o1 is not null!");
}
else
{
logger.Error("o1 is null ", 88);
}
// MarshalByRefObject mbro1 = null;
// mbro1 = o1 as MarshalByRefObject;
// if (mbro1!= null)
// {
// logger.Debug("Mbro1 is not null!");
// }
// else
// {
// logger.Error("Mbro1 is null ", 88);
//
// }
// return RemotingServices.Marshal(mbro1);
IAdapter a1 = o1 as IAdapter;
if ( a1 == null )
{
logger.Error(" as is null !", 88);
return null;
}
else
{
logger.Debug(" o1 as a1 will be returned !");
return a1;
}
}
Jim Hsu - 15 Sep 2004 01:34 GMT tried, not working :-) can load assembly, but can't not simply return that interface. :-) working on other solution now.
Hi Jim,
Now make sure to put the assembly into GAC, tell me as it goes... regards
-- José Miguel Torres jtorres_diaz~~ARROBA~~terra.es http://jmtorres.blogspot.com
"Jim Hsu" <orice.bug@nospam.msa.hinet.net> escribió en el mensaje news:erCLtcZmEHA.3428@TK2MSFTNGP14.phx.gbl... I use a remote factory to dynamic load the .net servicedComponent , and return as an fixed interface.
it does not work. , the error below, , the funny thing is that when I add reference to this .net servicedcomponent in the client, it will work, however, apparently this break the idea of "dynamic".
the same code work perfectly for a component inheritant from MarshalByRefObject in stead., so it seems the code is ok, just does not work with serviced component.
I pasted to code below: can anyone tell what is going wrong. If I am going on the wrong direction, let me know, I need COM+ for object pooling, application recycling, statistics ...etc. I don't like to build thing from the scratch, the truth that MS is hold us to wait for Indigo in 2+ years, is not a good news for us building enterprise application .net application ... sigh..., just $.02
"Event Type: Error Event Source: Sharkgrin.tigerCon Event Category: (78) Event ID: 888 Date: 9/13/2004 Time: 9:25:54 PM User: N/A Computer: LUNAR1 Description: con error ----------------LogPack Statck Trace ------------------- Error at offset 137 in file:line:column d:\j\depot\bluestar\integration\main\instrumentations\logpack\logpack.cs:756:6 CheethasCon3 at offset 314 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:235:5 Main at offset 13 in file:line:column d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:41:4
System.Runtime.Serialization.SerializationException: Insufficient state to deserialize the object. More information is needed.
Server stack trace: at System.UnitySerializationHolder.GetRealObject(StreamingContext context) at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder) at System.Runtime.Serialization.ObjectManager.DoFixups() at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm) at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeMessageParts(MemoryStream stm) at System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage.FixupForNewAppDomain() at System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage reqMsg)
Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at Sharkgrin.RemoteFactory.LoadAdapter(String assemblyFile, String typeName, Object[] constructArgs) in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\remotefactory.cs:line 27 at Sharkgrin.tigerCon.CheethasCon3() in d:\j\depot\bluestar\integration\main\core\msghandler\tiger\tigercon2\tigercon2.cs:line 226
For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp. "
source code
public static void conDoe4()
{
Console.WriteLine("ConDoe4() in use!");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = doeFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
setup.ApplicationName = "AdapterDoeLoader";
//AppDomain appDomain1 = "DoeLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
a1 = factory1.LoadAdapter("Doe", "Sharkgrin.Doe", null);
logger.Debug("doe loaded!");
logger.Info("Doe.SendReceive(1234abcd) = " + a1.SendReceive("1234abcd"));
}
public static void CheethasCon3()
{
logger.Debug(" CheethasCon 3 : using AppDomain RemoteLoader !");
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = adapterFolder;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
//setup.PrivateBinPath = adapterFolder;
setup.ApplicationName = "AdapterLoader";
AppDomain appDomain1 = AppDomain.CreateDomain("RemoteLoaderDomain",
null, setup);
RemoteFactory factory1 = ( RemoteFactory )
appDomain1.CreateInstanceFromAndUnwrap("tigerCon2.exe",
"Sharkgrin.RemoteFactory");
IAdapter a1 = null;
try
{
a1 = factory1.LoadAdapter("cheethasJr",
"BlueStar.Integration.Adapters.CheethasJr",null);
logger.Debug( "or1 returned ");
}
catch(Exception e)
{
logger.Error("con error", e, 888);
Thread.Sleep(77000);
}
if (a1 == null)
{
logger.Error("a1 is null",888);
}
else
{
logger.Info(" as.sendReceive " + a1.SendReceive("1234abced, from remote a.."));
}
}
public class RemoteFactory : MarshalByRefObject
{
static readonly LogPack logger LogPack.GetLogger(typeof(RemoteFactory));
private const BindingFlags bfi =
BindingFlags.Instance | BindingFlags.Public |
BindingFlags.CreateInstance ;
public IAdapter LoadAdapter( string assemblyFile,
string typeName,object[] constructArgs )
{
logger.Debug("Create() -> tassemblyFile : " + assemblyFile +
"typeName = " + typeName);
logger.Debug("AppDomain Base : " + AppDomain.CurrentDomain.BaseDirectory );
logger.Debug("Appdomain FreindlyName = " + AppDomain.CurrentDomain.FriendlyName);
logger.Info( "\tRelativeSearchPath : " + AppDomain.CurrentDomain.RelativeSearchPath);
logger.Info("\tPrivateBinPath : " + AppDomain.CurrentDomain.SetupInformation.PrivateBinPath);
logger.Debug("assembly loading ...!");
Assembly ass1 = Assembly.Load(assemblyFile);
if (ass1 == null)
{
logger.Error(" ass1 is null ", 888);
}
else
{
logger.Debug(" ass1 is not null !" );
}
object o1 = ass1.CreateInstance( typeName);
// ObjectHandle oh1 = .CreateInstanceFrom( assemblyFile,
// typeName,false, bfi, null, constructArgs,null,null,null);
//
// object o1 = oh1.Unwrap();
if (o1!= null)
{
logger.Debug("o1 is not null!");
}
else
{
logger.Error("o1 is null ", 88);
}
// MarshalByRefObject mbro1 = null;
// mbro1 = o1 as MarshalByRefObject;
// if (mbro1!= null)
// {
// logger.Debug("Mbro1 is not null!");
// }
// else
// {
// logger.Error("Mbro1 is null ", 88);
//
// }
// return RemotingServices.Marshal(mbro1);
IAdapter a1 = o1 as IAdapter;
if ( a1 == null )
{
logger.Error(" as is null !", 88);
return null;
}
else
{
logger.Debug(" o1 as a1 will be returned !");
return a1;
}
}
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|