Author |
Message
|
smdavies99 |
Posted: Fri Nov 01, 2013 4:02 am Post subject: Global Cache - Error BIP7198 |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
I'm getting BIP7198 when trying to load an object into the GlobalCache
(Windows 7 - Version 8.0.0.3)
Quote: |
Only certain types of values are valid for use with the global cache.
When using the Java interface, a value must implement either the 'Serializable' or 'Externalizable' interface.
Any other Java objects are invalid values.
|
My question is how (or indeed if) are people loading java objects into the cache. The map.put function uses an object
Code: |
Object com.ibm.broker.plugin.MbGlobalMap.put(Object arg0, Object arg1) throws MbException
|
so how do you put an object such as this into the cache and later extract it?
Code: |
static class SParts {
String ID;
String PartNumber;
String Descr;
String Supplier;
String SupplierId;
String UsedOn; }
|
This may seem easy to some people but I'm not an experienced Java Developer. _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
joebuckeye |
Posted: Fri Nov 01, 2013 4:35 am Post subject: Re: Global Cache - Error BIP7198 |
|
|
 Partisan
Joined: 24 Aug 2007 Posts: 365 Location: Columbus, OH
|
If the code snippet is your class definition then it looks like you need to add " implements Serializable" since the error message mentions that.
Code: |
static class SParts implements Serializable {
String ID;
String PartNumber;
String Descr;
String Supplier;
String SupplierId;
String UsedOn; }
|
|
|
Back to top |
|
 |
Esa |
Posted: Fri Nov 01, 2013 4:42 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
Global cache (in version 8 ) doesn't actually support storing objects as values. Objects can only be stored if they can be serialized into strings.
To implement for example Externalizable interface, you will have to add writeExternal and readExternal methods in your class. In these methods you must write code for exporting the object as a string and for instantiating an object from the string representation. Global cache will call these methods when storing/retrieving the values.
Last edited by Esa on Fri Nov 01, 2013 4:44 am; edited 1 time in total |
|
Back to top |
|
 |
smdavies99 |
Posted: Fri Nov 01, 2013 4:43 am Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
Thanks for the response. I tried that and it says
Code: |
Serializable cannot be resolved to a type
|
There are some 'setter' and 'getter' functions in the class. I don't know if that makes a difference?
{I'm well out of my depth here} _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
smdavies99 |
Posted: Fri Nov 01, 2013 5:05 am Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
Ok. I changed it to 'implements Externalizable' and added the two mandatory functions
Code: |
public void writeExternal(ObjectOutput out) throws IOException {
public void ReadExternal(ObjectOutput out) throws IOException, ClassNotFoundException {
|
And got a load of java errors.
Code: |
2013-11-01 13:01:29.234054 324 UserTrace BIP3484E: ''CWOBJ0006W: An exception occurred: java.lang.ClassNotFoundException: com.sita.broker.globalcache.allparts$SParts
at java.lang.Class.forNameImpl(Native Method)
at java.lang.Class.forName(Class.java:184)
at com.ibm.ws.xs.io.ObjectStreamPool$ClassForNamePrivilegedAction.run(ObjectStreamPool.java:372)
at com.ibm.ws.xs.io.ObjectStreamPool$ClassForNamePrivilegedAction.run(ObjectStreamPool.java:341)
at java.security.AccessController.doPrivileged(AccessController.java:277)
at com.ibm.ws.xs.io.ObjectStreamPool$ReusableInputStream.resolveClass(ObjectStreamPool.java:300)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1596)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1501)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1755)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1334)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:353)
at com.ibm.ws.objectgrid.map.BaseMap$BaseMapObjectTransformer.inflateObject(BaseMap.java:6622)
at com.ibm.ws.objectgrid.map.BaseMap$BaseMapObjectTransformer.inflateValue(BaseMap.java:6577)
at com.ibm.ws.objectgrid.map.LogSequenceImpl.inflate(LogSequenceImpl.java:2044)
at com.ibm.ws.objectgrid.map.LogSequenceImpl.inflate(LogSequenceImpl.java:1762)
at com.ibm.websphere.objectgrid.plugins.LogSequenceTransformer.inflate(LogSequenceTransformer.java:145)
at com.ibm.ws.objectgrid.event.ClientReadWriteRequestSystemEvent.readEvent(ClientReadWriteRequestSystemEvent.java:325)
at com.ibm.ws.objectgrid.ServerCoreEventProcessor.initRequestEvent(ServerCoreEventProcessor.java:1949)
at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processClientServerRequest(ServerCoreEventProcessor.java:2042)
at com.ibm.ws.objectgrid.ShardImpl.processMessage(ShardImpl.java:1033)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:600)
at com.ibm.CORBA.iiop.ClientDelegate$1.run(ClientDelegate.java:1106)
at java.security.AccessController.doPrivileged(AccessController.java:277)
at com.ibm.CORBA.iiop.ClientDelegate.invoke(ClientDelegate.java:1101)
at com.sun.proxy.$Proxy6.processMessage(Unknown Source)
at com.ibm.ws.objectgrid.partition._IDLShardStub.processMessage(_IDLShardStub.java:480)
at com.ibm.ws.objectgrid.client.ORBClientCoreMessageHandler.sendMessage(ORBClientCoreMessageHandler.java:468)
at com.ibm.ws.objectgrid.client.ORBClientCoreMessageHandler.sendReadWriteRequest(ORBClientCoreMessageHandler.java:1075)
at com.ibm.ws.objectgrid.client.RemoteTransactionCallbackImpl.processReadWriteRequestAndResponse(RemoteTransactionCallbackImpl.java:970)
at com.ibm.ws.objectgrid.client.RemoteTransactionCallbackImpl.commit(RemoteTransactionCallbackImpl.java:283)
at com.ibm.ws.objectgrid.SessionImpl.commit(SessionImpl.java:1846)
at com.ibm.ws.objectgrid.SessionImpl.mapPostInvoke(SessionImpl.java:3434)
at com.ibm.ws.objectgrid.ObjectMapImpl.postInvoke(ObjectMapImpl.java:795)
at com.ibm.ws.objectgrid.ObjectMapImpl.put(ObjectMapImpl.java:573)
at com.ibm.ws.objectgrid.ObjectMapImpl.put(ObjectMapImpl.java:523)
at com.ibm.broker.cachesupport.MbGlobalMapInternal.put(MbGlobalMapInternal.java:248)
at com.ibm.broker.plugin.MbGlobalMap.put(MbGlobalMap.java:431)
at com.sita.broker.globalcache.allparts.loadapartcache(airport.java:122)
''
An embedded component has written the diagnostic message included here.
Refer to the appropriate message in the embedded component's documentation.
2013-11-01 13:01:29.234380 324 UserTrace BIP3484E: ''CWOBJ1130W: Communication with the partition with the domain:grid:mapSet:partitionId WMB_DEVBRKR_localhost_12809_DEVBRKR_localhost_12813:WMB:mapSet:7 failed with an Object Request Broker (ORB) exception communicating with <null> at Broker8002.lan. org.omg.CORBA.INTERNAL: An internal error happened processing the request''
|
Oh well, 10 steps backwards. I knew that there was a reason I never took to Java. sigh.
 _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
mqjeff |
Posted: Fri Nov 01, 2013 5:35 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
ReadExternal is not the same as readExternal.
The camel needs more than just it's nose in the tent...
If you've got a class that consists of a set of strings, then the method to serialize it should consist of a big long string concatenation operation, with a delimiter between each field, and the method to deserialize should use a string tokenizer to break it apart at the delimiter. |
|
Back to top |
|
 |
Esa |
Posted: Fri Nov 01, 2013 5:42 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
smdavies99 wrote: |
Ok. I changed it to 'implements Externalizable' and added the two mandatory functions
Code: |
public void writeExternal(ObjectOutput out) throws IOException {
public void ReadExternal(ObjectOutput out) throws IOException, ClassNotFoundException {
|
And got a load of java errors.
Code: |
2013-11-01 13:01:29.234054 324 UserTrace BIP3484E: ''CWOBJ0006W: An exception occurred: java.lang.ClassNotFoundException: com.sita.broker.globalcache.allparts$SParts
at java.lang.Class.forNameImpl(Native Method)
at java.lang.Class.forName(Class.java:184)
at |
|
I could be wrong, but it looks as if your SParts class lacked a constructor method. |
|
Back to top |
|
 |
smdavies99 |
Posted: Fri Nov 01, 2013 5:50 am Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
mqjeff wrote: |
ReadExternal is not the same as readExternal.
The camel needs more than just it's nose in the tent...
If you've got a class that consists of a set of strings, then the method to serialize it should consist of a big long string concatenation operation, with a delimiter between each field, and the method to deserialize should use a string tokenizer to break it apart at the delimiter. |
so the 'Object' in the definition below is not really a general purpose object at all but essentially a String one?
Code: |
Object com.ibm.broker.plugin.MbGlobalMap.put(Object arg0, Object arg1) throws MbException
|
I can't see if the cache feature implemented in V9 have changed or not. So far it appears not and that the subset of eXtremeCache used is fairly dumb. (I could be wrong here)
So I added something to serialize the object values into a string with a delimiter and now get the following error (sigh)
Code: |
java.lang.ClassCastException: java.lang.String incompatible with [Ljava.lang.String;'
|
Oh well back to searching for this one. _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
mqjeff |
Posted: Fri Nov 01, 2013 5:58 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
Actually, in v9, you can use Strings for name/value cache entries, but you can use general purpose java objects for value cache entries.
But, yes, in v8, it's strings or nothing.
And yes, it's a *subset* of ExtremeScale functionality. For use *within* Broker only.
You want the full range of ExtremeScale functionality? From within broker? First, buy ExtremeScale. |
|
Back to top |
|
 |
stoney |
Posted: Fri Nov 01, 2013 6:05 am Post subject: |
|
|
Centurion
Joined: 03 Apr 2013 Posts: 140
|
Hi,
The BIP7198 is unfortunately rather misleading - in WMB v8.0, you can't store anything in the Global Cache other than primitive types and String values (or simple arrays of those types).
In IIB v9.0, we now allow any Serializable or Externalizable types to be stored directly in the Global Cache. However, the classes to be used cannot be deployed to the integration server, and must instead be placed in the shared-classes directory.
Since you are using WMB v8.0, you will have to convert your object into a compatible type and store that type in the Global Cache instead.
You could add code to convert your SParts object to and from a String:
Code: |
class SParts {
String ID;
String PartNumber;
String Descr;
String Supplier;
String SupplierId;
String UsedOn;
String toCacheString() { return string representing data within this object }
static SParts fromCacheString(String data) { return new SParts object created by decoding the string }
}
|
Then convert the SParts object to a String and store the String in the Global Cache:
Code: |
MbGlobalMap theMap = MbGlobalMap.getGlobalMap();
SParts mySParts = new SParts();
String serializedSParts = mySParts.toCacheString();
theMap.put(mykey, serializedSParts);
|
Then when retrieving the String from the Global Cache, convert it back into a SParts object:
Code: |
MbGlobalMap theMap = MbGlobalMap.getGlobalMap();
String serializedSParts = theMap.get(mykey);
SParts mySParts = SParts.fromCacheString(serializedSParts);
|
|
|
Back to top |
|
 |
smdavies99 |
Posted: Fri Nov 01, 2013 6:31 am Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
Ok. I got the loading to work
for some reason just doing:-
Code: |
String[] str_serial = new String[1];
str_serial[0] = ID + "|" + PartNumber + "|" + Descr + "|" + Supplier + "|" + SupplierId + "|" UsedOn;
|
Still failed when map.put was used with str_serial[0]
however
Code: |
String[] str_serial = new String[1];
String myStr;
myStr = ID + "|" + PartNumber + "|" + Descr + "|" + Supplier + "|" + SupplierId + "|" UsedOn;
str_serial[0] = myStr.toString();
|
worked.
now to work out the best way to de-tokenize the data on the way out. _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
mqjeff |
Posted: Fri Nov 01, 2013 6:38 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
smdavies99 wrote: |
now to work out the best way to de-tokenize the data on the way out. |
StringTokenizer |
|
Back to top |
|
 |
Y75 |
Posted: Fri Nov 01, 2013 9:41 am Post subject: |
|
|
Apprentice
Joined: 29 Jul 2013 Posts: 32
|
I think the simplest way is to convert object to byte[] and store it in global cache in v8. I think i did that if I remember correctly. Now I am on v9.
I wouldn't get into string manipulation. Here is code to convert java object to byte array. Objects have to implement serializable.
[code]ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
byte bytes[] = bos.toByteArray();
[code] |
|
Back to top |
|
 |
smdavies99 |
Posted: Fri Nov 01, 2013 9:53 am Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
I have got it all working just in time for Beer O'Clock (here in Blighty).\
Quite why Java is so dumb as to treat Java Strings and Jave String Arrays a effectively different data types is frnkly beyond me. I had to use .toString in places that I shouldn't have to. Pah! Bah Humbug.
Anyway I have three caches set up with the same data and different keys. This covers all the uses where we have to look up values using keys.
Now I just need to document the process so that others who are more inept at Java development than myself can continue the development process for the remainder of the static data we need to load into the Cache. That can wait for another week. Now it is time for a pint or so of T.E.A.
Thanks for the hints.  _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
|