Search code examples
javajson-lib

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?


Solution

  • 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;
          }
       }