开发者

NoSuchMethodError with JSON-Lib and JDK 1.4

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜