I recompiled the Quartz DLL as a part of rebuilding the server apps.
Now I cannot read the BLOB data for the jobs I scheduled before the
recompile. I get a JobPersistenceException thrown from the
JobDetail.RetrieveJob method.
Full text of exception message:
Couldn't retrieve job because the BLOB couldn't be deserialized: Could
not load file or assembly 'Quartz, Version=1.0.3.2, Culture=neutral,
PublicKeyToken=f6b8c98a402cc8a4' or one of its dependencies. The located
assembly's manifest definition does not match the assembly reference.
(Exception from HRESULT: 0x80131040)
Is there a way to work around this? Is there a way to save without
being version specific? I'd really like to be able to migrate to the
next release of Quartz.Net without having to recreate all of the
scheduled jobs, and this looks like it could cause an issue.
Brad Bruce
Brad Bruce
--
You received this message because you are subscribed to the Google Groups
"Quartz.NET" group.
To post to this group, send email to quar...@googlegroups.com.
To unsubscribe from this group, send email to
quartznet+...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/quartznet?hl=en.
Are other serialization techniques, such as JSON, on the drawing board?
Brad
Brad
--
I just committed to GitHub master support for pluggable serialization
strategy. I did some tests but didn't get DataContractJSONSerializer
to work yet. The basic thing you would need are:
properties["quartz.serializer.type"] =
typeof(JSONObjectSerializer).AssemblyQualifiedName;
and the actual implementation (not working yet):
public class JSONObjectSerializer : IObjectSerializer
{
public byte[] Serialize<T>(T obj) where T : class
{
DataContractJsonSerializer serializer = new
DataContractJsonSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
return ms.ToArray();
}
}
public T DeSerialize<T>(byte[] data) where T : class
{
using (MemoryStream ms = new MemoryStream(data))
{
DataContractJsonSerializer serializer = new
DataContractJsonSerializer(typeof(T));
var readObject = serializer.ReadObject(ms);
return (T) readObject;
}
}
}
Maybe this is a start. The problem could be the open typing used here.
Ideas and enhancements are always welcome.
-Marko
public byte[] Serialize(IDictionary<string, object> values)
{
using (var stream = new MemoryStream())
using (var writer = new BinaryWriter(stream))
{
writer.Write(values.Count);
foreach (var pair in values)
{
writer.Write(pair.Key);
var code = pair.Value != null ? Type.GetTypeCode(pair.Value.GetType()) : TypeCode.Empty;
writer.Write((byte) code);
if (pair.Value != null)
{
switch (code)
{
case TypeCode.DateTime:
writer.Write(((DateTime) pair.Value).Ticks);
break;
case TypeCode.String:
writer.Write((string)pair.Value);
break;
case TypeCode.Boolean:
writer.Write((bool) pair.Value);
break;
case TypeCode.Char:
writer.Write((char) pair.Value);
break;
case TypeCode.Single:
writer.Write((float)pair.Value);
break;
case TypeCode.Double:
writer.Write((double)pair.Value);
break;
case TypeCode.Decimal:
writer.Write((decimal) pair.Value);
break;
case TypeCode.SByte:
writer.Write((sbyte)pair.Value);
break;
// remaining integer types...
default:
throw new Exception("Type not supported");
}
}
}
writer.Flush();
return stream.ToArray();
}
}
public IDictionary<string, object> Deserialize(byte[] data)
{
var values = new Dictionary<string, object>();
using (var stream = new MemoryStream(data))
using (var reader = new BinaryReader(stream))
{
var count = reader.ReadInt32();
for (var i = 0; i < count; i++)
{
var key = reader.ReadString();
var code = (TypeCode) reader.ReadByte();
object value;
switch (code)
{
case TypeCode.Empty:
value = null;
break;
case TypeCode.DateTime:
value = new DateTime(reader.ReadInt64());
break;
case TypeCode.String:
value = reader.ReadString();
break;
case TypeCode.Boolean:
value = reader.ReadBoolean();
break;
case TypeCode.Byte:
value = reader.ReadByte();
break;
case TypeCode.Char:
value = reader.ReadChar();
break;
case TypeCode.Single:
value = reader.ReadSingle();
break;
case TypeCode.Double:
value = reader.ReadDouble();
break;
case TypeCode.Decimal:
value = reader.ReadDecimal();
break;
case TypeCode.SByte:
value = reader.ReadSByte();
break;
// remaining integer types...
default:
throw new Exception("Type not supported");
}
values.Add(key, value);
}
}
return values;
}
-Marko
> --
> You received this message because you are subscribed to the Google Groups
> "Quartz.NET" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/quartznet/-/eBq8D4e3swgJ.
I had to remove AllowPartiallyTrustedCallers for .NET 4.0 build
because of custom serialization for now, but I believe the semantics
have changed anyway so it might not be necessary anymore.
-Marko