Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.IllegalArgumentException: Non-positive maxBytesPerChar

We have multithreaded java application which is doing file operation and initializing charset encoding as below.

Charset charset;
CharsetDecoder decoder;
CharsetEncoder encoder;
String charsetCoding = CharsetUtil.getJVMCharset();                        
charset = Charset.forName(charsetCoding);
decoder = charset.newDecoder();
encoder = charset.newEncoder();  // Exception is thrown from this line

We recently started to see the exception below randomly during execution, when we try to reprocess same file, it gets processed without any error, google is of no help as we couldn't find anything with similar error,

Caused by: java.lang.IllegalArgumentException: Non-positive maxBytesPerChar
    at java.nio.charset.CharsetEncoder.<init>(CharsetEncoder.java:175)
    at java.nio.charset.CharsetEncoder.<init>(CharsetEncoder.java:209)
    at sun.nio.cs.ISO_8859_1$Encoder.<init>(ISO_8859_1.java:116)
    at sun.nio.cs.ISO_8859_1$Encoder.<init>(ISO_8859_1.java:113)
    at sun.nio.cs.ISO_8859_1.newEncoder(ISO_8859_1.java:46)
    at myClass.readFile

Appreciate if someone can provide any help, direction in this.

I can't seem to find the full source code for jdk 5(source I have does not contain code for sun.* packages) I decompiled the Encoder class and I can't see how is this possible as code is passing hard coded value "1.0" here.

class ISO_8859_1$Encoder extends CharsetEncoder
{
  private final Surrogate.Parser sgp = new Surrogate.Parser();

  private ISO_8859_1$Encoder(Charset paramCharset)
  {
    super(paramCharset, 1.0F, 1.0F);
  }

I have the source of CharsetEncoder as below, which is getting <0 value eventhough encoder passed 1.0

protected CharsetEncoder(Charset cs,
             float averageBytesPerChar,
             float maxBytesPerChar)
{
this(cs,
     averageBytesPerChar, maxBytesPerChar,
     new byte[] { (byte)'?' });
}

"This" calls below function

 protected
CharsetEncoder(Charset cs,
       float averageBytesPerChar,
       float maxBytesPerChar,
       byte[] replacement)
{
this.charset = cs;
if (averageBytesPerChar <= 0.0f)
    throw new IllegalArgumentException("Non-positive "
                       + "averageBytesPerChar");
if (maxBytesPerChar <= 0.0f)
    throw new IllegalArgumentException("Non-positive "
                       + "maxBytesPerChar");***
if (!Charset.atBugLevel("1.4")) {
    if (averageBytesPerChar > maxBytesPerChar)
    throw new IllegalArgumentException("averageBytesPerChar"
                       + " exceeds "
                       + "maxBytesPerChar");
like image 408
user2112430 Avatar asked Nov 12 '22 10:11

user2112430


1 Answers

Have a look at: http://docs.oracle.com/javase/7/docs/api/java/nio/charset/CharsetEncoder.html

At the end of the text at the beginning of the API, it says: "Instances of this class are not safe for use by multiple concurrent threads."

Are you using a single CharsetEncoder object in multiple threads?

like image 50
Zhe Avatar answered Nov 15 '22 05:11

Zhe