I've downloaded the supposedly latest JDK 1.3 compatible binary named json-lib-2.4-jdk13.jar and am getting the following error.
Exception in thread "main" java.lang.NoSuchMethodError: java.lang.ThreadLocal: method remove()V not found
at net.sf.json.AbstractJSON.removeInstance(AbstractJSON.java:221)
I checked the JDK 1.4 API and noticed that remove method on a ThreadLocal is indeed unsupported, and only added in JDK 1.5
The offending开发者_运维知识库 code is:
protected static void removeInstance(Object instance)
{
Set set = getCycleSet();
set.remove(instance);
if (set.size() == 0)
cycleSet.remove();
}
Does anyone know if I've missed something obvious here, or need an additional download or something?
Set#remove(Object) is certainly defined in Java 1.3. The error is actually saying that ThreadLocal#remove()V does not exist. That came in 1.5. (See? No such method!)
Here is the source of the bug in json-lib 2.4 (jdk1.3)
AbstractJSON:
/**
* Removes a reference for cycle detection check.
*/
protected static void removeInstance( Object instance ) {
Set set = getCycleSet();
set.remove( instance );
if(set.size() == 0) {
cycleSet.remove(); // BUG @ "line 221"
}
}
Since in CycleSet.java we see:
private static class CycleSet extends ThreadLocal {
protected Object initialValue() {
return new SoftReference(new HashSet());
}
public Set getSet() {
Set set = (Set) ((SoftReference)get()).get();
if( set == null ) {
set = new HashSet();
set(new SoftReference(set));
}
return set;
}
}
But ThreadLocal (1.3) has no such method.
[edit after @AlexR answer/comment]:
Given that the lib is open source, I think this may fix it (not tested):
private static class CycleSet extends ThreadLocal {
protected Object initialValue() {
return new SoftReference(new HashSet());
}
/** added to support JRE 1.3 */
public void remove() {
this.set(null);
}
public Set getSet() {
Set set = (Set) ((SoftReference)get()).get();
if( set == null ) {
set = new HashSet();
set(new SoftReference(set));
}
return set;
}
}
I have just examined the code of Thread and ThreadLocal. I think that if you can at least control the command line you are using to run your application you can try to create special version of Thread that is a merge of Thread from java 1.3 with Thread from java 1.5: add thread local support.
Then fix a little bit ThreadLocal itself: remove generics and AtomicInteger used once there.
Now create jar that creates these 2 classes and put them to bootstrap classpath when you are running the application.
And a lot of good luck. If you are lucky this will probably work.
精彩评论