【问题标题】:java Strings odd behavior with collatorjava字符串与整理器的奇怪行为
【发布时间】:2016-12-23 22:12:36
【问题描述】:

使用compareIgnoreCase 时,我得到NegativeArraySizeException / 'NullPointerException'(在Java 7 JRE 中运行)。

Caused by: java.lang.NegativeArraySizeException
    at java.lang.String.toCharArray(String.java:2748)
    at sun.text.normalizer.NormalizerImpl.canonicalDecomposeWithSingleQuotation(NormalizerImpl.java:2506)
    at java.text.RBTableBuilder.build(RBTableBuilder.java:107)
    at java.text.RBCollationTables.<init>(RBCollationTables.java:83)
    at java.text.RuleBasedCollator.<init>(RuleBasedCollator.java:300)
    at java.text.RuleBasedCollator.<init>(RuleBasedCollator.java:281)
    at java.text.Collator.getInstance(Collator.java:276)

Caused by: java.lang.NullPointerException
    at java.lang.String.length(String.java:623)
    at java.text.RBTableBuilder.build(RBTableBuilder.java:84)
    at java.text.RBCollationTables.<init>(RBCollationTables.java:83)
    at java.text.RuleBasedCollator.<init>(RuleBasedCollator.java:300)
    at java.text.RuleBasedCollator.<init>(RuleBasedCollator.java:281)
    at java.text.Collator.getInstance(Collator.java:276)

这些似乎发生在 String.compareIgnoreCase 和 String.equalsIgnoreCase

示例代码:

  public static int compareIgnoreCase(Locale locale, String a, String b) {
    if (a != null && a.length() == 0) {
      a = null;
    }
    if (b != null && b.length() == 0) {
      b = null;
    }
    //
    if (a == b) {
      return 0;
    }
    if (a == null) {
      return -1;
    }
    if (b == null) {
      return 1;
    }
    Collator collator = Collator.getInstance(locale);
    collator.setStrength(Collator.SECONDARY);
    return collator.compare(a, b);
  }

调用者:

  public static int compareIgnoreCase(String a, String b) {
    return compareIgnoreCase(NlsUtility.getDefaultLocale(), a, b);
  }

NlsUtility.getDefaultLocale:

  public static Locale getDefaultLocale() {
    Locale locale = LocaleThreadLocal.get();
    if (locale == null) {
      locale = Locale.getDefault();
    }
    return locale;
  }

问题似乎又回来了,然后是 JVM 崩溃。我不知道如何解决这个问题:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f1dabb9d4f0, pid=4290, tid=139765228910336
#
# JRE version: Java(TM) SE Runtime Environment (7.0_80-b15) (build 1.7.0_80-b15)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.80-b11 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x7ee4f0]  nmethod::can_unload(BoolObjectClosure*, OopClosure*, oopDesc**, bool)+0x70
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /tmp/hs_err_pid4290.log
Compiled method (c2) 191914528 4305  s!         java.text.Collator::getInstance (157 bytes)
 total in heap  [0x00007f1da19f7f90,0x00007f1da19fa8f8] = 10600
 relocation     [0x00007f1da19f80b0,0x00007f1da19f8290] = 480
 constants      [0x00007f1da19f82a0,0x00007f1da19f82c0] = 32
 main code      [0x00007f1da19f82c0,0x00007f1da19f9980] = 5824
 stub code      [0x00007f1da19f9980,0x00007f1da19f9a40] = 192
 oops           [0x00007f1da19f9a40,0x00007f1da19f9b30] = 240
 scopes data    [0x00007f1da19f9b30,0x00007f1da19fa3d0] = 2208
 scopes pcs     [0x00007f1da19fa3d0,0x00007f1da19fa690] = 704
 dependencies   [0x00007f1da19fa690,0x00007f1da19fa6a8] = 24
 handler table  [0x00007f1da19fa6a8,0x00007f1da19fa8d0] = 552
 nul chk table  [0x00007f1da19fa8d0,0x00007f1da19fa8f8] = 40
Compiled method (c2) 191914528 4305  s!         java.text.Collator::getInstance (157 bytes)
 total in heap  [0x00007f1da19f7f90,0x00007f1da19fa8f8] = 10600
 relocation     [0x00007f1da19f80b0,0x00007f1da19f8290] = 480
 constants      [0x00007f1da19f82a0,0x00007f1da19f82c0] = 32
 main code      [0x00007f1da19f82c0,0x00007f1da19f9980] = 5824
 stub code      [0x00007f1da19f9980,0x00007f1da19f9a40] = 192
 oops           [0x00007f1da19f9a40,0x00007f1da19f9b30] = 240
 scopes data    [0x00007f1da19f9b30,0x00007f1da19fa3d0] = 2208
 scopes pcs     [0x00007f1da19fa3d0,0x00007f1da19fa690] = 704
 dependencies   [0x00007f1da19fa690,0x00007f1da19fa6a8] = 24
 handler table  [0x00007f1da19fa6a8,0x00007f1da19fa8d0] = 552
 nul chk table  [0x00007f1da19fa8d0,0x00007f1da19fa8f8] = 40
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#

【问题讨论】:

  • 由于代码中的错误,您会遇到异常(恕我直言,这是可以自我解释和清楚的)。如果您自己找不到原因,请尝试发布重现问题的最小代码快照。
  • 您为locale 变量传递了什么值?我认为如果locale 变量为空或不是有效的语言环境,就会发生此错误。
  • 我无法使用此代码重现您的错误,传递您指定的语言环境。您确定您正在通过该语言环境,而不是其他语言环境吗?也许您可以在调用 Collator.getInstance 之前使用调试器检查 locale 的值。
  • 好的,我刚刚阅读了您的最后一条评论。我想知道附加调试器是否会以某种方式影响语言环境。您可以尝试在不使用调试器的情况下运行,但将行 System.out.println(LocaleData.getCollationData(locale).getString("Rule")); 放在对 Collator.getInstance 的调用之前。如果这显示为 null,那么您的 Java 运行时中的语言环境数据存在问题,您可能应该转移到更高版本的 Java 版本。
  • 嗯,在内部,语言环境保存在缓存中。也许那个缓存以某种方式损坏了。在这一点上进行验尸是不可能的。我认为这里的任何人都无法为您提供任何进一步的帮助,抱歉。

标签: java string


【解决方案1】:

似乎这个错误导致了 JVM 段错误。如果您有类似的问题,可以查看How do I debug Segfaults occurring in the JVM when it runs my code?

【讨论】:

    【解决方案2】:

    您必须在调用 Collat​​or.getInstance(locale);之前检查您的 locale

    检查它是否为空,是否具有无效的长度()或有效的语言环境。尝试调试您的应用程序。这将为您提供一些关于那里正在发生的事情的建议。

    显然,您 compareIgnoreCase 引发了异常(Nullpointer),但我建议调试您的应用程序,因为这是由于您的检查中的代码失败或可能在 Collat​​or.getInstance() 期间...

    【讨论】:

    • 语言环境是使用 Locale.forLanguageTa‌​g("nl-BE") 设置的,在方法调用之前,有一个空检查。如果语言环境为空,则使用 Locale.getDefault 编辑:我不确定成功实例化的 Locale 对象如何具有“无效长度”
    • 您有日志可以为我们提供一些帮助您的信息吗?
    • Nullpointer 实际上是在 java.lang.String.length(String.java:623) 提出的
    • 我认为它从 java.text.Collat​​or.getInstance(Collat​​or.java:276) 开始。我正在阅读有关 forLanguageTa‌g("...") 的内容,也许您的 Locale 实例对于一些奇怪的东西来说格式不正确。很抱歉,我无法提取更多信息..
    • 应用程序中只有三种可能的语言环境:nl-BE、fr-BE、Locale.getDefault。我不确定这三个有什么奇怪的。它们是有效的语言环境。并且异常停止发生,无需对代码进行任何干预。
    猜你喜欢
    • 1970-01-01
    • 2012-07-19
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2017-08-07
    • 1970-01-01
    相关资源
    最近更新 更多