java - DateTime compareTo 不适用于 DateTime

标签 java eclipse datetime jodatime

已接受答案的调查和详细信息在问题的评论中。

我有一个小型 Java 项目,它读取时间表并将 Joda-Time Intervals 放入排序的 map (在本例中为 TreeMap)以进行进一步处理。 这是通过 ScheduledExecutorService 完成的:

executor.scheduleWithFixedDelay(new Runnable() {
        @Override
        public void run() {
            try {
                doWork();
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }, 1, 1, TimeUnit.SECONDS);

doWork() 然后读取文件,创建一些间隔,然后使用此比较器(在 map 构造函数中指定)填充 map :

@Override
public int compare(Interval o1, Interval o2) {
  return o1.getStart().compareTo(o2.getStart());
}

代码随后在插入第一个间隔时在比较器中中断。 通常我会认为间隔本身有问题,但是我检查了几种可能性并注意到我迷失了很多奇怪的事情:

  • 间隔很好,o1o2 是具有相同长时间戳的有效 DateTime。
  • 没有捕获到异常。线程刚刚停止工作。
  • 当我从 Eclipse 启动应用程序时,一切正常。它仅在启动已部署版本时中断。我所说的部署是指它被打包到一个 .jar 中并复制到一个共享目录中,这里没有容器。
  • 改变

    try {
      doWork();
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
    

    try {
      doWork();
    } catch (Throwable e) {
      e.printStackTrace();
      throw new RuntimeException(e);
    }
    

    修复它。 (即 map 填充良好,包括原始的第一个间隔)。

最后一部分让我认为这是 JIT 或 JVM 的错误,而不是代码的错误。 我还探讨了这是构建问题的可能性,但似乎并非如此:

  • Eclipse 和构建服务器都使用 Java 7(Eclipse 7.0.51,构建服务器:7.0.25,使用 7.0.51 JRE 启动部署版本)
  • Joda 时间库版本在 Eclipse 和部署的 lib 文件夹 (2.1) 中都是相同的
  • 这不是一个新功能,完全相同的代码在不同的分支中工作,并且已经有几个星期了
  • 我已经尝试阻止 Eclipse 使用它自己的缓存 Ivy 库,而是使用部署目录中的库。同样的东西 - 在 Eclipse 中工作,在使用 Java 启动 jar 时不起作用。

经过一些远程调试后,我重现了类似的内容:带有签名“(Lorg/joda/time/ReadableInstant;)I”的方法“compareTo”不适用于此对象在比较器代码中设置断点时,目标对象为 class org.joda.time.DateTime

任何有关如何进一步调试的帮助将不胜感激。

编辑:

private void doWork() {
        SortedMap<Interval, String> map = new TreeMap<>(new Comparator<Interval>() {
            @Override
            public int compare(Interval o1, Interval o2) {
                return o1.getStart().compareTo(o2.getStart());
            }
        });

        Collection<String> col1 = new HashSet<>();
        Collection<String> col2 = new HashSet<>();
        String string = "";
        long ts = 0;

        try (FileInputStream input = new FileInputStream(fileName);
                InputStreamReader isr = new InputStreamReader(input);
                BufferedReader reader = new BufferedReader(isr)) {
            String line = reader.readLine();
            map.put(new Interval(new DateTime(), new DateTime()), "");
        }
}

虽然由于有很多额外代码,这看起来不像 SSCCE,但如果我删除 Collection 声明或读取的行,或在 try block 之前将任何内容放入映射中(然后按原样执行其余部分)-一切正常。让我想到竞争条件,但是这里涉及的所有变量都是本地的(除了 fileName,它保证已经设置)。

此外,在尝试一些东西时,我发现从 2.1 切换到 Joda-time 2.3 显然可以解决问题。但是,我在他们的错误修复更新日志中看不到任何看起来甚至相关的内容。

最佳答案

这里是根据我的评论总结的答案:

远程端是否有第二个 JodaTime 版本?也许是 2.0 版之前的旧版本,其中 Comparable-handling 发生了一点变化(请参阅通用接口(interface) ReadableInstant)?在 2.0 之前,有问题的方法具有签名 compareTo(Object),而在 2.0 和更高版本中具有新签名 compareTo(ReadableInstant),另请参见 release notes .两个 joda-jar 和一个连接的类加载问题的这种情况将解释以下异常消息:

带有签名“(Lorg/joda/time/ReadableInstant;)I”的方法“compareTo”不适用于此对象,目标对象是 org.joda.time.DateTime 类。

(您的问题很棘手,值得更多投票。很高兴听到您在包含较旧 JodaTime 版本的 JRuby 库中找到了原因。)

关于java - DateTime compareTo 不适用于 DateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22810331/

相关文章:

java - 打开一个关于 eclipse 启动的透视图 - 以编程方式

java - 为什么在我们具有与方法参数相同的泛型列表的以下两个方法调用中存在差异?

java eclipse 格式化(如果条件不必要的空白)

java - 在 Android 和 iOS 中本地使用 krpano 的问题

c# - 如何在 C#/SQL Server 中跟踪重复的日历事件?

java.io.UnsupportedEncodingException : unicode-1-1-utf-7?

java - mongoclientoptions 与 mongoclientsettings 之间的区别

android - Eclipse 停止提供默认建议

php - 在 PHP 中查找上个月的最后一天

php - 根据特定时区将当前时间插入mysql数据库