Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid version number: Version number may be negative or greater than 255

I am getting below error when I try to access a page in my application.

SEVERE: Servlet.service() for servlet [jsp] threw exception
java.lang.IllegalArgumentException: Invalid version number: Version number may be negative or greater than 255
    at com.ibm.icu.util.VersionInfo.getInstance(VersionInfo.java:191)
    at com.ibm.icu.impl.ICUDebug.getInstanceLenient(ICUDebug.java:65)
    at com.ibm.icu.impl.ICUDebug.<clinit>(ICUDebug.java:69)

I assume that it is due to some version mismatch. How can I trace the issue? The application is not mavenized and hence I am not sure how to check the issue. Atleast if I know which jarfile is giving issue then it will be good.

like image 221
JAVA_CAT Avatar asked Sep 24 '20 05:09

JAVA_CAT


5 Answers

TLDR; replace your icu4j.jar file with the latest version.

This is likely caused by an older version of ICU4J in your classpath. The VersionInfo class was limited to 2-character version numbers, setting a limit to 255. Since Java 8 is now at 1.8.0_291, the 291 exceeds the 2-character limit, causing the ICU4J VersionInfo exception.

ICU-21219 is fixed in ICU4J:68.1

like image 184
Thomas Taylor Avatar answered Nov 10 '22 04:11

Thomas Taylor


The problem is resolved as I downgraded my java version.

like image 31
JAVA_CAT Avatar answered Nov 10 '22 05:11

JAVA_CAT


If you don't want to upgrade ICU just call this little helper function before the ICU stuff get's called:

/**
 * There is a bug in an old ICU version that stops ICU from working when the JDK patch version is larger than 
 * 255 (like in jdk 1.8.0_261). To work around that we change the local version number, init ICU and change it
 * back then.
 */
private void icuHack() {
    String javaVersion = System.getProperty("java.version");
    int idxOfUnderscore = javaVersion.indexOf('_');
    if( idxOfUnderscore == -1 ) {
        return;
    }
    int patchVersion = Integer.parseInt(javaVersion.substring(idxOfUnderscore+1));
    if( patchVersion < 256 ) {
        return;
    }
    log.info("Java version '"+javaVersion+"' contains patch version >255, need to do ICU hack.");
    System.setProperty("java.version", "1.8.0_254");
    new com.ibm.icu.impl.ICUDebug();
    System.setProperty("java.version", javaVersion);
}
like image 35
Daniel Avatar answered Nov 10 '22 04:11

Daniel


Well, I know it is a dirty hack but setting the "java.version" property to a version that doesn't contain numbers >255 worked for me:

System.setProperty("java.version", "1.8.0_254");

Just set it before the class is loaded (first access) and restore the original value afterwards. And file a bug to the author of the library since this is just a workaround.

like image 33
René Avatar answered Nov 10 '22 03:11

René


I solved this problem by excluding old icu4j package,eg:

    <dependency>
        <groupId>jaxen</groupId>
        <artifactId>jaxen</artifactId>
        <version>1.1.6</version>
        <exclusions>
            <exclusion>
                <groupId>com.ibm.icu</groupId>
                <artifactId>icu4j</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

then refer to the latest icu4j package:

    <dependency>
        <groupId>com.ibm.icu</groupId>
        <artifactId>icu4j</artifactId>
        <version>68.2</version>
    </dependency>
like image 31
Brook Avatar answered Nov 10 '22 03:11

Brook