-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
7u45
-
linux
FULL PRODUCT VERSION :
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
$ uname -a
Linux ayanichkin-desktop 3.11.0-14-generic #21-Ubuntu SMP Tue Nov 12 17:04:55 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
I need custom 1-byte charset, that actually stored in database. But when I attempt encode some text with it, I received IllegalArgumentException (some inputs processed correctly always, some only sometimes).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use attached source code of 1-byte table charset. Output copied from http://www.compileonline.com/compile_java_online.php, but on my machine this also fails.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Encoded byte array with my charset.
ACTUAL -
# Compiling the source code....
$javac Table1ByteCharset.java 2>&1
# Executing the program....
$java -Xmx128M -Xms16M Table1ByteCharset
Exception in thread "main" java.lang.IllegalArgumentException
at java.nio.Buffer.position(Buffer.java:236)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:600)
at java.lang.StringCoding.encode(StringCoding.java:370)
at java.lang.String.getBytes(String.java:939)
at Table1ByteCharset.main(Table1ByteCharset.java:56)
REPRODUCIBILITY :
This bug can be reproduced often.
---------- BEGIN SOURCE ----------
import java.util.Arrays;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
public class Table1ByteCharset extends Charset {
// Encode each char with its position in table, [0; 255].
final char[] table = new char[255];
class Encoder extends CharsetEncoder {
Encoder() {
super(Table1ByteCharset.this, 1.0f, 1.0f, new byte[]{(byte)'?'});
}
@Override
protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
while (in.remaining() > 0) {
if (out.remaining() == 0) {
return CoderResult.OVERFLOW;
}
final int b = indexOf(in.get());
if (b < 0) {
return CoderResult.unmappableForLength(1);
}
out.put((byte)b);
}
return CoderResult.UNDERFLOW;
}
}
class Decoder extends CharsetDecoder {
Decoder() {
super(Table1ByteCharset.this, 1.0f, 1.0f);
}
@Override
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
while (in.remaining() > 0) {
if (out.remaining() == 0) {
return CoderResult.OVERFLOW;
}
out.put(table[ index(in.get()) ]);
}
return CoderResult.UNDERFLOW;
}
private int index(byte b) {return b < 0 ? 256 + (int)b : (int)b;}
}
Table1ByteCharset() {super("Table1ByteCharset", null);}
@Override
public boolean contains(Charset cs) {return this == cs;}
@Override
public Encoder newEncoder() {return new Encoder();}
@Override
public Decoder newDecoder() {return new Decoder();}
public static void main(String[] args) {
System.out.println(Arrays.toString("Hello World".getBytes(new Table1ByteCharset())));
}
int indexOf(char ch) {
for (int i = 0; i < table.length; ++i)
if (table[i]==ch) return i;
return -1;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
In my case I just not use Charset subclass.
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
$ uname -a
Linux ayanichkin-desktop 3.11.0-14-generic #21-Ubuntu SMP Tue Nov 12 17:04:55 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
I need custom 1-byte charset, that actually stored in database. But when I attempt encode some text with it, I received IllegalArgumentException (some inputs processed correctly always, some only sometimes).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use attached source code of 1-byte table charset. Output copied from http://www.compileonline.com/compile_java_online.php, but on my machine this also fails.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Encoded byte array with my charset.
ACTUAL -
# Compiling the source code....
$javac Table1ByteCharset.java 2>&1
# Executing the program....
$java -Xmx128M -Xms16M Table1ByteCharset
Exception in thread "main" java.lang.IllegalArgumentException
at java.nio.Buffer.position(Buffer.java:236)
at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:600)
at java.lang.StringCoding.encode(StringCoding.java:370)
at java.lang.String.getBytes(String.java:939)
at Table1ByteCharset.main(Table1ByteCharset.java:56)
REPRODUCIBILITY :
This bug can be reproduced often.
---------- BEGIN SOURCE ----------
import java.util.Arrays;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;
public class Table1ByteCharset extends Charset {
// Encode each char with its position in table, [0; 255].
final char[] table = new char[255];
class Encoder extends CharsetEncoder {
Encoder() {
super(Table1ByteCharset.this, 1.0f, 1.0f, new byte[]{(byte)'?'});
}
@Override
protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
while (in.remaining() > 0) {
if (out.remaining() == 0) {
return CoderResult.OVERFLOW;
}
final int b = indexOf(in.get());
if (b < 0) {
return CoderResult.unmappableForLength(1);
}
out.put((byte)b);
}
return CoderResult.UNDERFLOW;
}
}
class Decoder extends CharsetDecoder {
Decoder() {
super(Table1ByteCharset.this, 1.0f, 1.0f);
}
@Override
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
while (in.remaining() > 0) {
if (out.remaining() == 0) {
return CoderResult.OVERFLOW;
}
out.put(table[ index(in.get()) ]);
}
return CoderResult.UNDERFLOW;
}
private int index(byte b) {return b < 0 ? 256 + (int)b : (int)b;}
}
Table1ByteCharset() {super("Table1ByteCharset", null);}
@Override
public boolean contains(Charset cs) {return this == cs;}
@Override
public Encoder newEncoder() {return new Encoder();}
@Override
public Decoder newDecoder() {return new Decoder();}
public static void main(String[] args) {
System.out.println(Arrays.toString("Hello World".getBytes(new Table1ByteCharset())));
}
int indexOf(char ch) {
for (int i = 0; i < table.length; ++i)
if (table[i]==ch) return i;
return -1;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
In my case I just not use Charset subclass.