Home » Eclipse Projects » Eclipse Platform » [De]serialization of objects in plugin
[De]serialization of objects in plugin [message #331737] |
Thu, 18 September 2008 15:39  |
Eclipse User |
|
|
|
Originally posted by: alexm.xxx.yyy
All:
Similar problems have been brought up and discussed here, but I still do
not see a clear solution.
One of my plugins (A) serializes an object (DataBucket) _from another
plugin (B)_ and saves it in a file. Trying to deserialize it back,
however, throws the ClassNotFoundException. I experimented with bundle
exports in the manifest file, but the only solution that worked was this:
1. Get a valid class loader from the plugin B that defines the
serialized object:
ClassLoader cl = DataBucket.class.getClassLoader();
2. subclass ObjectInputStream to override its resolveClass() method, and
make it use the class loader from step 1:
public class MyObjectInputStream extends ObjectInputStream {
private ClassLoader classLoader;
public MyObjectInputStream(InputStream in, ClassLoader cl)
throws IOException {
super(in);
classLoader = cl;
}
@Override
protected Class<?> resolveClass(final ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
String name = desc.getName();
try {
Class<?> klass = Class.forName(name, false, classLoader);
return klass;
} catch (ClassNotFoundException ex) {
throw ex;
}
}
}
3. In plugin A, deserialize the object, using MyObjectInputStream:
ObjectInputStream in = new MyObjectInputStream(inputStream,
DataBucket.class.getClassLoader());
return in.readObject();
I do not like this solution. I must be able to resolve this within the
means provided by Eclipse framework, without resorting to method overrides.
Any suggestions?
Thanks,
Alex Molochnikov
Kelman Technologies Inc.
Note: the plugin B that defines DataBucket exports its package via the
Export-Package manifest header, and the plugin A that does the
serialization declares plugin B in its Require-Bundle header. However,
this does not make this class accessible to the class loader when it is
invoked by the standard ObjectInputStream.
|
|
| | | | |
Re: [De]serialization of objects in plugin [message #331762 is a reply to message #331761] |
Fri, 19 September 2008 21:14   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
--------------060205040803020400000103
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Alex,
I suspect the problem you described is the opposite of the actual
problem. You might find that adding this to the MANIFEST.MF of the base
plugin will help:
Eclipse-BuddyPolicy: dependent
I added this to EMF's Ecore plugin so that the Ecore plugin itself is
able to serialize and deserialize objects from any plugin that depends
on Ecore.
Eclipse-BuddyPolicy: dependent
Alex Molochnikov wrote:
> Paul Webster wrote:
>> ...
>> It doesn't, at least not any more than any container provider (think
>> JEE). If you can see an upstream plugin, you can serialized those
>> objects. In your example, if A requires plugin B, then it's not
>> problem.
>> ...
>
> For a moment I thought that I understood the problem. Now I am confused.
>
> My plugin A does require plugin B. It is listed in the plugin A's
> manifest (in Require-Bundle header). Yet, when A attempts to
> deserialize an object from one of B's classes, the exception is thrown.
>
> Scratching my head...
>
> Alex Molochnikov
--------------060205040803020400000103
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Alex,<br>
<br>
I suspect the problem you described is the opposite of the actual
problem. You might find that adding this to the MANIFEST.MF of the base
plugin will help:<br>
<blockquote>Eclipse-BuddyPolicy: dependent<br>
</blockquote>
I added this to EMF's Ecore plugin so that the Ecore plugin itself is
able to serialize and deserialize objects from any plugin that depends
on Ecore.<br>
<br>
<br>
Eclipse-BuddyPolicy: dependent<br>
<br>
Alex Molochnikov wrote:
<blockquote cite="mid:gb1hdk$46e$1@build.eclipse.org" type="cite">Paul
Webster wrote:
<br>
<blockquote type="cite">...
<br>
It doesn't, at least not any more than any container provider (think
JEE). If you can see an upstream plugin, you can serialized those
objects. In your example, if A requires plugin B, then it's not
problem.
<br>
....
<br>
</blockquote>
<br>
For a moment I thought that I understood the problem. Now I am
confused.
<br>
<br>
My plugin A does require plugin B. It is listed in the plugin A's
manifest (in Require-Bundle header). Yet, when A attempts to
deserialize an object from one of B's classes, the exception is thrown.
<br>
<br>
Scratching my head...
<br>
<br>
Alex Molochnikov
<br>
</blockquote>
</body>
</html>
--------------060205040803020400000103--
|
|
| |
Re: [De]serialization of objects in plugin [message #331764 is a reply to message #331763] |
Sat, 20 September 2008 00:01   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
--------------040103020903060900060508
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Alex,
I suspect there's something going on you've left out. If plugin A
depends on plugin B, it should be able to load the classes from plugin
B, as Paul already suggested... Can you reproduce this problem with a
simple test case you could share?
Alex Molochnikov wrote:
> Ed,
>
> Thank you for the advice. I set up my plugin A manifest like this:
>
> Eclipse-ResgisterBuddy: B
>
> In plugin B's manifest I have:
>
> Eclipse-BuddyPolicy: dependent
>
> No luck.
>
> Alex
>
> "Ed Merks" <Ed.Merks@gmail.com <mailto:Ed.Merks@gmail.com>> wrote
> in message news:gb1iql$sd5$2@build.eclipse.org...
> Alex,
>
> I suspect the problem you described is the opposite of the actual
> problem. You might find that adding this to the MANIFEST.MF of the
> base plugin will help:
>
> Eclipse-BuddyPolicy: dependent
>
> I added this to EMF's Ecore plugin so that the Ecore plugin itself
> is able to serialize and deserialize objects from any plugin that
> depends on Ecore.
>
>
> Eclipse-BuddyPolicy: dependent
>
--------------040103020903060900060508
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Alex,<br>
<br>
I suspect there's something going on you've left out. If plugin A
depends on plugin B, it should be able to load the classes from plugin
B, as Paul already suggested... Can you reproduce this problem with a
simple test case you could share?<br>
<br>
<br>
Alex Molochnikov wrote:
<blockquote cite="mid:gb1n01$3nl$1@build.eclipse.org" type="cite">
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<meta content="MSHTML 6.00.2737.800" name="GENERATOR">
<style></style>
<div><font face="Arial" size="2">Ed,</font></div>
<div> </div>
<div><font face="Arial" size="2">Thank you for the advice. I set up
my plugin A manifest like this:</font></div>
<div> </div>
<div><font face="Arial" size="2">Eclipse-ResgisterBuddy: B</font></div>
<div> </div>
<div><font face="Arial" size="2">In plugin B's manifest I have:</font></div>
<div> </div>
<div><font face="Arial" size="2">Eclipse-BuddyPolicy: dependent</font></div>
<div> </div>
<div><font face="Arial" size="2">No luck.</font></div>
<div> </div>
<div><font face="Arial" size="2">Alex</font></div>
<blockquote dir="ltr"
style="border-left: 2px solid rgb(0, 0, 0); padding-right: 0px; padding-left: 5px; margin-left: 5px; margin-right: 0px;">
<div>"Ed Merks" <<a moz-do-not-send="true"
href="mailto:Ed.Merks@gmail.com">Ed.Merks@gmail.com</a>> wrote in
message <a moz-do-not-send="true"
href="news:gb1iql$sd5$2@build.eclipse.org">news:gb1iql$sd5$2@build.eclipse.org</a>...</div>
Alex,<br>
<br>
I suspect the problem you described is the opposite of the actual
problem. You might find that adding this to the MANIFEST.MF of the base
plugin will help:<br>
<blockquote>Eclipse-BuddyPolicy: dependent<br>
</blockquote>
I added this to EMF's Ecore plugin so that the Ecore plugin itself is
able to serialize and deserialize objects from any plugin that depends
on Ecore.<br>
<br>
<br>
Eclipse-BuddyPolicy: dependent</blockquote>
</blockquote>
</body>
</html>
--------------040103020903060900060508--
|
|
|
Re: [De]serialization of objects in plugin [message #331765 is a reply to message #331764] |
Sat, 20 September 2008 00:43   |
Eclipse User |
|
|
|
Originally posted by: NOBODY.NOSPAM.COM
This is a multi-part message in MIME format.
------=_NextPart_000_0063_01C91AA9.191C2580
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Ed,
I will try putting together a small test case on Sunday.
Thanks,
Alex
"Ed Merks" <Ed.Merks@gmail.com> wrote in message =
news:gb1si5$5vb$1@build.eclipse.org...
Alex,
I suspect there's something going on you've left out. If plugin A =
depends on plugin B, it should be able to load the classes from plugin =
B, as Paul already suggested... Can you reproduce this problem with a =
simple test case you could share?
------=_NextPart_000_0063_01C91AA9.191C2580
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type =
content=3Dtext/html;charset=3DISO-8859-1>
<META content=3D"MSHTML 6.00.2737.800" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY text=3D#000000 bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Ed,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>I will try putting together a small =
test case on=20
Sunday.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2>Thanks,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>Alex</FONT></DIV>
<BLOCKQUOTE dir=3Dltr=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
<DIV>"Ed Merks" <<A=20
href=3D"mailto:Ed.Merks@gmail.com">Ed.Merks@gmail.com</A>> wrote in =
message=20
<A=20
=
href=3D"news:gb1si5$5vb$1@build.eclipse.org">news:gb1si5$5vb$1@build.ecli=
pse.org</A>...</DIV>Alex,<BR><BR>I=20
suspect there's something going on you've left out. If plugin A =
depends=20
on plugin B, it should be able to load the classes from plugin B, as =
Paul=20
already suggested... Can you reproduce this problem with a =
simple test=20
case you could share?</BLOCKQUOTE></BODY></HTML>
------=_NextPart_000_0063_01C91AA9.191C2580--
|
|
| | |
Re: [De]serialization of objects in plugin [message #331769 is a reply to message #331767] |
Sat, 20 September 2008 19:15   |
Eclipse User |
|
|
|
This is a multi-part message in MIME format.
--------------010203010701070004030200
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Alex,
Adding this to
Eclipse-BuddyPolicy: dependent
the org.apache.commons.lang plugin solved the problem. The
SerializationUtils class seems kind of useless in the context of Eclipse
class loading without some type of buddy loading schema. I'm not sure
with whom to take up an issue like this. The path of least resistance
is to just use this instead of the utility commons utility:
ObjectInputStream inputStream = new ObjectInputStream(new
ByteArrayInputStream(data));
DataBucket bucket = (DataBucket)inputStream.readObject();
You wouldn't even need the buddy stuff in this case, since the second
plugin where you do this can already load all the classes.
Alex Molochnikov wrote:
> Ed,
>
> I've put together a small test case that demonstrates the problem.
>
> The serializable class is in com.kelman.serialization plugin (referred
> to as plugin B in my previous posts). It is just an empty class
> (DataBucket) that extends Object, implements Serializable interface,
> and adds no instance vars.
>
> The com.kelman.serialization.test plugin (a.k.a. plugin A) is a JUnit
> test that has two classes:
>
> Serializer - serializes DataBucket and saves it in a file
> (C:/tmp/serialization.test).
>
> Deserializer - attempts to read the file into a byte buffer and
> deserialize it into the DataBucket object.
>
> When Deserializer is run as a plain JUnit test, it works. When the
> same test is run as JUnit PLug-in test, it throws the
> ClassNotFoundException.
>
> Please have a look at the MANIFEST.MF files in both plugins to spot
> any irregularities.
>
> Thank you very much for your help.
>
> Alex Molochnikov
>
>
> Ed Merks wrote:
>> Alex,
>>
>> I suspect there's something going on you've left out. If plugin A
>> depends on plugin B, it should be able to load the classes from
>> plugin B, as Paul already suggested... Can you reproduce this
>> problem with a simple test case you could share?
--------------010203010701070004030200
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Alex,<br>
<br>
Adding this to <br>
<blockquote>Eclipse-BuddyPolicy: dependent<br>
</blockquote>
the org.apache.commons.lang plugin solved the problem. The
SerializationUtils class seems kind of useless in the context of
Eclipse class loading without some type of buddy loading schema. I'm
not sure with whom to take up an issue like this. The path of least
resistance is to just use this instead of the utility commons utility:<br>
<br>
ObjectInputStream inputStream = new ObjectInputStream(new
ByteArrayInputStream(data));<br>
DataBucket bucket = (DataBucket)inputStream.readObject();<br>
<br>
You wouldn't even need the buddy stuff in this case, since the second
plugin where you do this can already load all the classes.<br>
<br>
<br>
Alex Molochnikov wrote:
<blockquote cite="mid:gb3ceh$prh$1@build.eclipse.org" type="cite">Ed,
<br>
<br>
I've put together a small test case that demonstrates the problem.
<br>
<br>
The serializable class is in com.kelman.serialization plugin (referred
to as plugin B in my previous posts). It is just an empty class
(DataBucket) that extends Object, implements Serializable interface,
and adds no instance vars.
<br>
<br>
The com.kelman.serialization.test plugin (a.k.a. plugin A) is a JUnit
test that has two classes:
<br>
<br>
Serializer - serializes DataBucket and saves it in a file
(C:/tmp/serialization.test).
<br>
<br>
Deserializer - attempts to read the file into a byte buffer and
deserialize it into the DataBucket object.
<br>
<br>
When Deserializer is run as a plain JUnit test, it works. When the same
test is run as JUnit PLug-in test, it throws the
ClassNotFoundException.
<br>
<br>
Please have a look at the MANIFEST.MF files in both plugins to spot any
irregularities.
<br>
<br>
Thank you very much for your help.
<br>
<br>
Alex Molochnikov
<br>
<br>
<br>
Ed Merks wrote:
<br>
<blockquote type="cite">Alex,
<br>
<br>
I suspect there's something going on you've left out. If plugin A
depends on plugin B, it should be able to load the classes from plugin
B, as Paul already suggested... Can you reproduce this problem with a
simple test case you could share?
<br>
</blockquote>
</blockquote>
</body>
</html>
--------------010203010701070004030200--
|
|
| |
Re: [De]serialization of objects in plugin [message #331771 is a reply to message #331770] |
Sun, 21 September 2008 13:45  |
Eclipse User |
|
|
|
Alex,
Comments below.
Alex Molochnikov wrote:
> Ed Merks wrote:
>> Alex,
>>
>> Adding this to
>>
>> Eclipse-BuddyPolicy: dependent
>>
>> the org.apache.commons.lang plugin solved the problem. The
>> SerializationUtils class seems kind of useless in the context of
>> Eclipse class loading without some type of buddy loading schema. I'm
>> not sure with whom to take up an issue like this.
>
> OK, I finally got it. Any object that gets [de]serialized must not
> have dependency on the third-party plugins unless those plugins set
> the buddy policy to "dependent".
No, that's not a good characterization of the problem. The problem is
as follows, as far as I understand it... The class loader used by the
underlying Java deserialization utilities seems to depend on the class
loader of the caller to the object stream's methods. So if you have a
utility method in SerializationUtils then the library in which the
SerializationUtils class itself appears needs to be able to see/load the
classes being loaded by the Java frameworks (and can't). But if you
copy that same deserialization code into a different library, as I did
by directly doing these same steps in the test class, then the class
loader for that library is used. That's why it works the way I wrote
it, the test plugin's class loader is used, but not by calling the
utility method in the framework library, which has a class loader that
doesn't see your plugins without some type of buddy policy.
>
> This can be a show-stopper, for the lack of control over those plugins.
If the libraries do need to do such things directly, in this case it's
just a utility class that you don't really need to use, then they really
do need to set up some type of buddy policy to be properly enabled. I
suggest you consider opening an Orbit bugzilla to draw attention to this
issue. If you do take the time (the issue will never be addressed if
you don't), please post the bugzilla number here.
> And even if modifying MANIFEST.MF is possible in the local copy of the
> plugin (as in the case with Apache plugins), it would be undesirable
> from the maintenance POV.
I agree. Though I think the value of the utility you're using is so
minimal as to be negligible, but it's still an issue worth raising.
>
> I ended up making a partial copy of SerializableUtils source, and
> included it into my plugin.
That's seems a good approach.
>
> Thank you very much for your help.
You're welcome.
>
> Alex
|
|
|
Goto Forum:
Current Time: Wed Apr 02 17:51:11 EDT 2025
Powered by FUDForum. Page generated in 0.05530 seconds
|