2011-08-03 36 views
3

我已经下载了所谓最新的JDK 1.3兼容二进制文件,名为json-lib-2.4-jdk13.jar,并且出现以下错误。使用JSON-Lib和JDK 1.4的NoSuchMethodError

Exception in thread "main" java.lang.NoSuchMethodError: java.lang.ThreadLocal: method remove()V not found 
    at net.sf.json.AbstractJSON.removeInstance(AbstractJSON.java:221) 

我查了JDK 1.4 API,发现在一个ThreadLocal是remove方法确实是不支持的,只有在JDK 1.5

有问题的代码是说:

protected static void removeInstance(Object instance) 
{ 
    Set set = getCycleSet(); 
    set.remove(instance); 
    if (set.size() == 0) 
    cycleSet.remove(); 
} 

有谁知道如果我在这里漏掉了一些明显的东西,或者需要额外下载什么东西?

+1

Java 1.3和1.4是非常古老的。你应该考虑升级。是的,这是工作的一点点了,但是这是不是以后遇到重大JDK错误(或OS不兼容)要好得多,在这一点上,你完全失去了运气 –

+0

[设置#删除(对象)](HTTP的:// download.oracle.com/javase/1.3/docs/api/java/util/Set.html#remove(java.lang.Object)) – alphazero

+0

@Adam当然你是对的。我正在研究一些遗留代码,并没有奢侈的更新jdk – Brad

回答

3

Set#remove(Object)肯定是defined in Java 1.3。该错误实际上是说ThreadLocal#remove()V不存在。那是1.5。 (见No such method!?)

这里是JSON-LIB 2.4(JDK1.3)的bug源

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" 
     } 
    } 

由于CycleSet.java我们看到:

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

但是ThreadLocal(1.3)没有这样的方法。

[编辑后@AlexR答案/评论]:

鉴于LIB是开源的,我觉得这可能修复它(未测试):

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; 
     } 
    } 
+2

感谢您确认我的怀疑。解决方法是恢复到早期版本的json-lib,所以它是在2.4版本中引入的。对于那些后续我得到的东西与版本2.3(json-lib-2。3-jdk13.jar) – Brad

+0

很棒。我认为这确实是一个BUG。由于您提到的特定版本专门针对Java 1.3和1.4版本运行。 –

0

我刚才检查的代码Thread和ThreadLocal。我认为,如果您至少可以控制您用来运行应用程序的命令行,则可以尝试创建特殊版本的Thread,它是将Java 1.3中的Thread与Java 1.5中的Thread合并在一起:添加线程本地支持。

然后修复一下ThreadLocal本身:删除泛型和AtomicInteger一次。

现在创建jar,创建这两个类,并在运行应用程序时将它们引导到引导类路径。

还有很多好运。如果你幸运的话,这可能会起作用。

+0

将CycleSet从其他东西中扩展出来会不会太简单?我们知道他们想要什么 - 线程范围的对象 - 和一个Map可以完成这项工作。 – alphazero

相关问题