SerializationException: Unable to find assembly

1,402 views
Skip to first unread message

tickzoom

unread,
Aug 10, 2009, 9:55:09 AM8/10/09
to NUnit-Discuss
Folks,

There's a new strange error appearing after all my tests pass in a
particular assembly. This has been working fine. Some, obviously must
have changed. Here's the full stack trace below and a few facts.

It showing an unhandled exception that is coming from a separate
AppDomain.

I added code to list the AppDomains and it shows:

AppDomains: nunit-console.exe
AppDomains: domain-TickZoomTesting.dll

NOTE: This particular test passes without the error if you run it
alone. It's only when running the entire assembly that this unhandled
exception error appears.

After searching the web high and low, nothing comes up as a possible
solution.

Tests run: 146, Failures: 0, Not run: 0, Time: 104.781 seconds

Unhandled exceptions:
1) TickZoom.System.TradingFramework.ExitStrategyTest.ShortStopTest :
System.Runtime.Serialization.SerializationException: Unable to find
assembly 'TickZoomAPI1.0, Version=1.0.3509.15764, Culture=neutral,
PublicKeyToken=null'.
at
System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly
()
at
System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType
(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor
(String objectName, String[] memberNames, BinaryTypeEnum[]
binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds,
ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo
assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap.Create
(String name, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA,
Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader
objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo,
SizedArray assemIdToAssemblyTable)
at
System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped
(BinaryObjectWithMapTyped record)
at
System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped
(BinaryHeaderEnum binaryHeaderEnum)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run
()
at
System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize
(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck,
Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize
(Stream serializationStream, HeaderHandler handler, Boolean fCheck,
Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at
System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject
(MemoryStream stm)
at System.AppDomain.Deserialize(Byte[] blob)
at System.AppDomain.UnmarshalObject(Byte[] blob)

Wayne Walter

unread,
Aug 10, 2009, 1:12:14 PM8/10/09
to NUnit-Discuss
After building NUnit from source, there's still no clue about this. I did find where
to prevent NUnit from failing to build due to this error. So I comment that and now
it still shows the unhandled exception error but at least allows the build to proceed.

Any clues?  I'm a bung up good debugger but his stack trace gives ZERO clues
as to what might cause the problem or even where to start looking. 

That DLL TickZoomApi1.0 that it says can't be found is reference and API used
by all the code so it is definitely there and working. So whey can't the stack
trace find it. And what it is serializing and why?  Makes zero sense.

Wayne

Charlie Poole

unread,
Aug 10, 2009, 1:12:12 PM8/10/09
to nunit-...@googlegroups.com
Hi,

> There's a new strange error appearing after all my tests pass
> in a particular assembly. This has been working fine. Some,
> obviously must have changed. Here's the full stack trace
> below and a few facts.
>
> It showing an unhandled exception that is coming from a
> separate AppDomain.
>
> I added code to list the AppDomains and it shows:
>
> AppDomains: nunit-console.exe
> AppDomains: domain-TickZoomTesting.dll

This is just the normal AppDomains one sees when running
NUnit console. Your tests are in the second domain.

> NOTE: This particular test passes without the error if you
> run it alone. It's only when running the entire assembly that
> this unhandled exception error appears.

Bugs in NUnit aside - and the stack trace shows us NUnit is not
involved here - an unhandled exception indicates that your test
code or the application you are testing threw an exception on
a thread and didn't catch it anywhere up the stack.

NUnit lists unhandled exceptions separately from errors because
there is no way to tell which of your tests started that thread.
For example, it's possible that of 1000 tests, #1 created the
thread and never terminated it. So we list the test that was
running when the exception was caught only as a hint. In your
case, it's most likely just the last test to be run.

Use the /run option to run groups of your tests and see what
happens. If you use namespaces, you can narrow it down rapidly
but if they are all in the same namespace, you'll have to run
each fixture. Eventually, you should be able to narrow it down
to one fixture or test that causes the problem.

One possibility is that something global in your app is causing
this. Frequently, the culprit is some sort of persistent logging
thread. In that case, tests that don't trigger the thread would
run alone without problem but others would cause it.

Good luck!

Charlie

Wayne Walter

unread,
Aug 10, 2009, 1:27:22 PM8/10/09
to nunit-...@googlegroups.com
Well, I recognize NUnit is not in the stack. But neither is anything in
my code. As you see, the namespace of all the stack frames are
System.Runtime or such related to remoting and serialization.

Here's some facts to consider why the problem might be in NUnit:

1. AppDomain.UnmarshalObject() method is at the root of the stack trace.

2. There is AppDomain involved and it was discovered that NUnit has
created a separate AppDomain. (didn't realize that before.) Whereas
my code never creates any AppDomain.

3. Since NUnit created the separate domains, it follows logic that NUnit
is the one trying to call AppDomain.UnmarshalObject. However, I searched
the NUnit code and there's no reference to that method.

4. You mention logging. I recently added log4net logging. It did build and run
nunit fine with log4net most of last week so it doesn't see directly related
to this problem.

5. However, I noticed that log4net is also used by NUnit, is there some kind
of conflict?

If after these facts, you still suspect it's a matter of narrowing down which
of my NUnit tests causes this, then I'll take that approach.

Sincerely,
Wayne


So who else would be trying to marshal across that App

Now you mention a logging thread. And, I did just recently add log4net logging
to the app. But again, none of that is referred to in the stack trace.

Charlie Poole

unread,
Aug 10, 2009, 1:32:07 PM8/10/09
to nunit-...@googlegroups.com
Hi Wayne,
 
Did I miss a post? What was the error you previously encountered in trying to build NUnit?
I was only aware of the runtime error in your first post.
 
Regarding the runtime error, I guess I didn't explain part of it in my first answer. After the
the exception was thrown and not handled on it's thread, NUnit's unhandled exception
handling tried to deal with it. But it seems like it was a custom exception defined in your
TickZoomApi1.0 assembly. That assembly is not known to NUnit in the primary AppDomain,
so it failed to serialize correctly between the secondary and primary AppDomains. This
is actually a new aspect of a known bug in how NUnit reports exceptions. (The new part
is that this is an unhandled exception)
 
So, my earlier answer still stands. NunitConsole.exe cannot find your assembly - nor
should we expect it to find it, since it's not in the AppBase or probing path for the
primary AppDomain. You still need to partition your tests in some way to narrow
down the problem. The bug in NUnit is that it should not be reporting the particular
stack trace you see but should just be saying "Stack trace not available."
 
Unhandled exceptions are tedious to deal with. I wish I had a simpler fix for you. :-(
 
Charlie
 

From: nunit-...@googlegroups.com [mailto:nunit-...@googlegroups.com] On Behalf Of Wayne Walter
Sent: Monday, August 10, 2009 10:12 AM
To: NUnit-Discuss
Subject: [nunit-discuss] Re: SerializationException: Unable to find assembly

Charlie Poole

unread,
Aug 10, 2009, 1:38:08 PM8/10/09
to nunit-...@googlegroups.com
Hi Wayne,
 
I'll let you catch up with my earlier answer. In summary...
 
The stack trace is from an error in NUnit's *processing* of the unhandled exception.
 
Unhandled exceptions normally give very little info anyway.
 
Brute force is called for here. :-)
 
Charlie
 
PS: NUnit doesn't use log4net in general for its logging. Only the pNUnit component
actually uses it because the guys who contributed that component had already been
using log4net. So if you were using pNUnit, then there could be an issue but it should
show up as a load error due to conflicting versions of log4net.
 
BTW, the NUnit gui displays log4net output if you use it, but it does so by dynamically
accessing your version of log4net and using reflection. This is pretty well tested and
doesn't cause problems.


From: nunit-...@googlegroups.com [mailto:nunit-...@googlegroups.com] On Behalf Of Wayne Walter
Sent: Monday, August 10, 2009 10:27 AM
To: nunit-...@googlegroups.com

Subject: [nunit-discuss] Re: SerializationException: Unable to find assembly

Wayne Walter

unread,
Aug 10, 2009, 1:52:57 PM8/10/09
to nunit-...@googlegroups.com
Oh. Now that was more helpful. However, after going through and double checking all the
custom exceptions and fixing a few of them to have [Serializable]. It still gives the same error.

Can you help with ideas on how to catch the unhandled exception myself? In theory if I can
catch the unhandled event within My test AppDomain then it won't fail due to the serialization
problem. Here's stuff I already tried:

I registered for the UnhandledException event from within the tests so it could catch and log
the exception but---it never fired the event.  According to docs, it looks like this always fires
to the default (or original) AppDomain if registered to catch it.

Can you suggest how to catch them ?  while I wait for your answer, I will try to register for
unhandled exceptions on the threads. to see if I can catch it that way.

Any other ideas?  I greatly appreciate your help. I'm only 2 years into .Net and see there's
still an ocean of stuff to learn different than Java.

Thanks!
Wayne

Wayne Walter

unread,
Aug 10, 2009, 2:17:25 PM8/10/09
to nunit-...@googlegroups.com
Success!  Catching the Application.ThreadException found the culprit with an comprehensible stack trace.
Still that except has the [Serializable] attribute. What do you have to do make the exceptions "pallatable" for NUnit to get them accross the AppDomain? It'd be nice to learn do make Exceptions "properly".

Wayne

Wayne Walter

unread,
Aug 10, 2009, 2:24:01 PM8/10/09
to nunit-...@googlegroups.com
Okay, found this link that teaches how to make Exceptions properly in detail. http://winterdom.com/2007/01/makeexceptionclassesserializable

Seems mine were missing the implemention of a constructor like this.

protected MyException(SerializationInfo info, StreamingContext ctxt) : base(info, ctxt) { }

Thanks, Charlie!  the case of the missing exception was solved.

Wayne

Charlie Poole

unread,
Aug 10, 2009, 2:25:15 PM8/10/09
to nunit-...@googlegroups.com
Hi Wayne,

> Oh. Now that was more helpful. However, after going through
> and double checking all the custom exceptions and fixing a
> few of them to have [Serializable]. It still gives the same error.

Exceptions should always be serializable, but that is probably not the
cause of your particular problem. If it were, you would get a much
clearer error message. This seems to be an exception that was serialized
successfully but could not be de-serialized in the primary AppDomain.

As I stated, this is expected: NUnit knows nothing about your custom
exceptions and no change you make can make it know about them. The
longer term solution to this problem for NUnit is that exceptions
should not be propogated across the remoting boundary. Rather the info
they contain should be encapsulated in a known type and that's what
should be serialized. But that's not any help for you today. :-(

> Can you help with ideas on how to catch the unhandled
> exception myself? In theory if I can catch the unhandled
> event within My test AppDomain then it won't fail due to the
> serialization problem. Here's stuff I already tried:

I can save you time by telling you you can't unless you have
control over the thread that is causing it. Simply *don't* let
any unhandled exceptions out of your threads.

> I registered for the UnhandledException event from within the
> tests so it could catch and log the exception but---it never
> fired the event. According to docs, it looks like this
> always fires to the default (or original) AppDomain if
> registered to catch it.

The UnhandledException event can *only* be used in the
primary AppDomain - which is the one NUnit is running in.

> Can you suggest how to catch them ? while I wait for your
> answer, I will try to register for unhandled exceptions on
> the threads. to see if I can catch it that way.

You can't register for unhandled exceptions but you can
catch them. Every Thread proc needs to have a try/catch
block. The catch can log the exception if nothing else.

> Any other ideas? I greatly appreciate your help. I'm only 2
> years into .Net and see there's still an ocean of stuff to
> learn different than Java.

You are far from the first person to run into this and I'm afraid
that narrowing it down to an offending test as best you can is the
only solution at this time. Any improvements to NUnit in this
regard will merely be for the purpose of helping you do that.

Charlie
> System.Runtime.Serialization.Formatters.Binary.__BinaryParser.
> ReadObjectWithMapTyped
> (BinaryObjectWithMapTyped record)
> at
>
> System.Runtime.Serialization.Formatters.Binary.__BinaryParser.
> ReadObjectWithMapTyped

Charlie Poole

unread,
Aug 10, 2009, 2:27:00 PM8/10/09
to nunit-...@googlegroups.com
Fantastic!
 
Regarding making custom exceptions go across the AppDomain, ask me again
after you read my last post. :-)
 
Charlie


From: nunit-...@googlegroups.com [mailto:nunit-...@googlegroups.com] On Behalf Of Wayne Walter
Sent: Monday, August 10, 2009 11:17 AM
To: nunit-...@googlegroups.com

Charlie Poole

unread,
Aug 10, 2009, 2:42:45 PM8/10/09
to nunit-...@googlegroups.com
Hi Wayne,
 
I honor your determination to solve this problem, and I see you're learning a
lot in the process. It's good that learning is it's own reward in this case. :-)
 
A few points repeated for emphasis:
 
1. NUnit does not know the definition of your exception so it can't construct
it from the data you serialize.
 
2. NUnit isn't expected to know the definition of your exception - there are
infinite possibilities of custom exceptions!
 
However, you should still make your exceptions properly serializable because
it's needed for other reasons.
 
If you're having trouble understanding any of my explanations, please feel
free to ask questions - I don't know your background and I may be glossing
some things over.
 
Charlie


From: nunit-...@googlegroups.com [mailto:nunit-...@googlegroups.com] On Behalf Of Wayne Walter
Sent: Monday, August 10, 2009 11:24 AM
To: nunit-...@googlegroups.com

Wayne Walter

unread,
Aug 10, 2009, 2:55:44 PM8/10/09
to nunit-...@googlegroups.com
You're correct. Even after adding the serialization, it still complained about not being able to find the assembly where that custom exception is defined.

Is there a way to solve that?  It seems that NUnit could catch that event that it can't resolve the assembly and then resolve it itself. I learned about that while researching this problem and tried it but they problem, I think, was that the event was happening in the "other" AppDomain. That was before I realized NUnit created 2 of them.

It seems NUnit could add that features to assume that whatever DLL it can't find will be in the same folder as the assembly under test. (That's where mine is). 

However, I confess, that will not always solve it for everyone.

But we should be able to find a smart generalized solution.

My interest in this wanes since I have now learned myself and have fixed my root problem.

But I spent almost 6 hours figuring this out due to the useless stack trace.

IN FACT, a much better solution would be to recognize in NUnit (as you said earlier)
that the stack trace is a SerializationException and therefore, most likely, useless so
it could then log a message like this"

WARNING: The stack trace below is likely useless because NUnit was unable to serialize
a custom exception into the primary AppDomain. To figure out this exception you need to
catch the exception inside your AppDomain handling the AppDomain.UnhandledException
and the Application.ThreadException events.

The the stack trace can follow since it might be useful in rare cases.

Sincerely,
Wayne

Sincerely,
Wayne

Charlie Poole

unread,
Aug 10, 2009, 4:01:05 PM8/10/09
to nunit-...@googlegroups.com
Hi Wayne,

> You're correct. Even after adding the serialization, it still
> complained about not being able to find the assembly where
> that custom exception is defined.

Exactly. Think of the serialized data as being the ingredients
and the assembly as containing the recipe for how too mix them
to create your cake - I mean object. :-)

> Is there a way to solve that? It seems that NUnit could
> catch that event that it can't resolve the assembly and then
> resolve it itself. I learned about that while researching
> this problem and tried it but they problem, I think, was that
> the event was happening in the "other" AppDomain. That was
> before I realized NUnit created 2 of them.

Not sure which one you mean by "other" but it probably doesn't
matter. Strictly speaking, NUnit creates one of them - your
test domain. The primary AppDomain is created by the runtime
for NUnit to run in.

> It seems NUnit could add that features to assume that
> whatever DLL it can't find will be in the same folder as the
> assembly under test. (That's where mine is).

It's not impossible, but a bit messy.

> However, I confess, that will not always solve it for everyone.
>
> But we should be able to find a smart generalized solution.

Yes, it would be better to devote time to a general solution.

Think of the problem this way: Two programs need to communicate -
nunit-console and your test. These two programs may be in different
AppDomains of the same process, or in different processes or even
on different computers. They can only do that by sharing some common
structure that they both define. Then they can use serialization,
.NET remoting, TCP, etc. but without that shared structure, there
can be no real communication - just bytes going back and forth.

Really, I was being approximate. The two programs in question are
actually two parts of NUnit, one of which is injected into the
appdomain/process/machine on which your tests are running. They
*can* share a common structure, which is how to solve this
problem. But that common structure can't be your custom
exception. It needs to be some generalized information
representation - like text, JSON or xml. That's our path
for the future.

> My interest in this wanes since I have now learned myself and
> have fixed my root problem.

Oh no! We were just starting to have fun. :-)

> But I spent almost 6 hours figuring this out due to the
> useless stack trace.
>
> IN FACT, a much better solution would be to recognize in
> NUnit (as you said earlier) that the stack trace is a
> SerializationException and therefore, most likely, useless so
> it could then log a message like this"
>
> WARNING: The stack trace below is likely useless because
> NUnit was unable to serialize a custom exception into the
> primary AppDomain. To figure out this exception you need to
> catch the exception inside your AppDomain handling the
> AppDomain.UnhandledException and the
> Application.ThreadException events.
>
> The the stack trace can follow since it might be useful in rare cases.

I don't think so - although it may be useful to me in fixing
this. That's because it's an exception thrown at the point where
NUnit is trying to access your exception - the stacktrace has
nothing whatsoever to do with your code. But we could still
construct a message that would point you in the right
direction.

It would be helpful if you could file a bug on this so
we don't forget to do something about it.

Charlie
> System.Runtime.Serialization.Formatters.Binary.__BinaryParser.
> ReadObjectWithMapTyped
>
> (BinaryObjectWithMapTyped record)
> at
>
> System.Runtime.Serialization.Formatters.Binary.__BinaryParser.
> ReadObjectWithMapTyped
Reply all
Reply to author
Forward
0 new messages