System.Runtime.Serialization.SerializationException: Unable to find assembly

1,814 views
Skip to first unread message

Stefan Falk

unread,
Jul 31, 2013, 7:49:52 AM7/31/13
to jni...@googlegroups.com
I created a bridge to a .dll file that depends on two other .dll files..


somehow I can access the Client.dll but when I access the Server.dll I receive:


Exception in thread "main" System.Runtime.Serialization.SerializationException: Unable to find assembly 'SibKernel.Server, Version=2.5.1.0, Culture=neutral, PublicKeyToken=null'.

Server stack trace: 
   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.BinaryConverter.TypeFromInfo(BinaryTypeEnum binaryTypeEnum, Object typeInformation, ObjectReader objectReader, BinaryAssemblyInfo assemblyInfo, InternalPrimitiveTypeE& primitiveTypeEnum, String& typeString, Type& type, Boolean& isVariant)
   at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadArray(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.CoreChannel.DeserializeBinaryResponseMessage(Stream inputStream, IMethodCallMessage reqMsg, Boolean bStrictBinding)
   at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream)
   at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)

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 SibKernel.Server.MasterBoardManager.GetConnectedMasterBoards()
   at SibKernel.Server.JavaWrapper.MasterBoardWrap.initialize()
   at SibKernel.Server.JavaWrapper.__MasterBoardWrap.initialize0(IntPtr __envp, JniLocalHandle __obj)
at sibkernel.server.javawrapper.MasterBoardWrap.initialize(Native Method)
at sibinterface.Main.main(Main.java:30)


I have no idea why it can not find the Server.dll but not the Client.dll. 

Can anyone help here?

Stefan Falk

unread,
Jul 31, 2013, 9:39:38 AM7/31/13
to jni...@googlegroups.com
Okay I was able to solve it using fuslogvw.exe http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.71).aspx

It showed me where the java application was looking for that specific .dll file 


*** Assembly Binder Log Entry  (31.07.2013 @ 15:20:09) ***
The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.
Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll
Running under executable  C:\Program Files\Java\jre7\bin\javaw.exe
--- A detailed error log follows. 
=== Pre-bind state information ===
LOG: User = EU\FalkStef
LOG: DisplayName = SibKernel.Client, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files/Java/jre7/bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).

Copying the file to C:/Program Files/Java/jre7/bin/ solved my issue - though I don't understand why it didn't look for it in that directory I specified by proxygen.exe's build.cmd:

csc .... /reference:"C:\jni4net\jni4net-0.8.6.0-bin\bin\SibKernel.Client.dll" ...

Laurent Cohen

unread,
Nov 25, 2014, 6:34:40 AM11/25/14
to jni...@googlegroups.com, stefan...@gmail.com
Hi Stefan,

I know I'm a bit late on this one, but I recently faced the exact same issue.
I found a solution that does not require to copy the DLL to the JRE's bin directory, as posted here: http://stackoverflow.com/a/23939713/524900

I hope this helps anyone with the same problem.

-Laurent

Laurent Cohen

unread,
Dec 3, 2014, 3:00:20 AM12/3/14
to jni...@googlegroups.com, stefan...@gmail.com
In fact, I implemented a more elegant (I think) solution to this particular problem. I wrote code to perform a one-time initialization in a static initializer, which enumerates the assemblies known to the jni4net bridge (Bridge.KnownAssemblies) and registers them using the core APIs as follows:

namespace test {
 
sealed class CustomizedBinder : SerializationBinder {
   
private static bool initDone = Init();

   
public override Type BindToType(string assemblyName, string typeName) {
     
return Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
   
}

   
private static bool Init() {
     
if (!initDone) {
        initDone
= true;
       
IList<Assembly> knownAssemblies = Bridge.KnownAssemblies;
       
if (knownAssemblies != null) {
         
foreach (Assembly a in knownAssemblies) {
           
if (a != null) Assembly.Load(a.FullName);
         
}
       
}
     
}
     
return true;
   
}
 
}
}

Then, the deserialization code uses the CustomizedBinder as follows:

public object Deserialize(byte[] bytes) {
 
Stream stream = new MemoryStream(bytes);
 
BinaryFormatter deserializer = new BinaryFormatter();
  deserializer
.Binder = new CustomizedBinder();
 
object o = deserializer.Deserialize(stream);
  stream
.Close();
 
return o;
}

I hope this helps.

-Laurent
Reply all
Reply to author
Forward
0 new messages