【问题标题】:NoSuchMethodError with JSON-Lib and JDK 1.4JSON-Lib 和 JDK 1.4 的 NoSuchMethodError
【发布时间】:2011-08-03 15:00:29
【问题描述】:

我已经下载了名为 json-lib-2.4-jdk13.jar 的所谓最新的 JDK 1.3 兼容二进制文件,但出现以下错误。

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

有谁知道我是否在这里遗漏了一些明显的东西,或者需要额外下载或其他什么?

【问题讨论】:

  • Java 1.3 和 1.4 已经很老了。你应该考虑升级。是的,现在有点工作,但这比以后遇到一个主要的 JDK 错误(或操作系统不兼容)要好得多,在这一点上你完全不走运
  • @Adam 是的,当然你是对的。我正在处理一些遗留代码,现在没有更新 jdk 的奢侈
  • @alphazero。谢谢你的帖子。我的问题是错误地说它是 Set 中缺少的 remove() 实际上问题出在 CylceSet 扩展的 ThreadLocal 上。我已经更新了我的问题
  • 这是库中的一个错误。查看答案。

标签: java json-lib


【解决方案1】:

Set#remove(Object) 肯定是defined in Java 1.3。该错误实际上是说 ThreadLocal#remove()V 不存在。那是在 1.5 中出现的。 (看到了吗?No such method!

这里是 json-lib 2.4 (jdk1.3) 中的错误来源

抽象JSON:

   /**
    * 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 回答/评论后编辑]:

鉴于该库是开源的,我认为这可能会解决它(未经测试):

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

【讨论】:

  • 感谢您确认我的怀疑。解决方法是恢复到 json-lib 的早期版本,因此它是在 2.4 版中引入的。对于那些跟随我的东西,我可以使用 2.3 版(json-lib-2.3-jdk13.jar)
  • 很棒的收获。我认为这确实是一个BUG。由于您提到的特定版本专门针对在 Java 1.3 和 1.4 版本上运行。
【解决方案2】:

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

然后修复一点 ThreadLocal 本身:删除曾经使用过的泛型和 AtomicInteger。

现在创建创建这 2 个类的 jar,并在您运行应用程序时将它们放入引导类路径。

祝你好运。如果你幸运的话,这可能会奏效。

【讨论】:

  • 从其他东西扩展 CycleSet 不是更简单吗?我们知道他们想要什么——线程范围的对象——并且 Map 可以完成这项工作。
猜你喜欢
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 2023-03-18
相关资源
最近更新 更多