String.getBytes() & String(byte[]) - java.nio.BufferOverflowException
The application in question uses JNI for legacy integration and I suspect the legacy code is corrupting the stack causing the above error. However, the error does not occur in Java 1.3, only Java 1.4.
Is there some way to suppress 1.4's use of the native IO API when encoding and decoding byte streams? This would at least provide a workaround in the meantime.
Thanks.
This is beginning to make a little sense. The problem is that you got a String and you don't want one. A String wraps an array of chars, which your app needs, right? Specifically they're chars because you need 16-bit char sets.
Presumably the getBytes() method call is used to get an array of bytes for some data transfer operation. java.nio was probably added in 1.4 as it has some very efficient ways of handling buffers as simultaneously of two or more types. It's trying to use the underlying char array as a byte array and there's a straight up bug someplace.
Workaround is strange to contemplate, but I'm pretty sure it will work: use String.getChars() to get an array of chars, and then use java.nio yourself to create your byte array! If you've never been there, it's not very hard. I use nio all the time and it's never been a problem.
Similar Messages
-
Java.nio.BufferOverflowException on big Strings ( 87MB)
Hi!
When calling getBytes() on a big String the following exception is thrown:
java.nio.BufferOverflowException
at java.nio.charset.CoderResult.throwException(Unknown Source)
at java.lang.StringCoding$CharsetSD.decode(Unknown Source)
at java.lang.StringCoding.decode(Unknown Source)
at java.lang.StringCoding.decode(Unknown Source)
at java.lang.String.<init>(Unknown Source)
at java.lang.String.<init>(Unknown Source)
at com.db.janus.Janus.main(Janus.java:99)
This happens as soon as the size of the String gets bigger than 92003848 bytes.
I can reproduce it with the following code:
String x = new String(new byte[92003848]); // --> OK
String x = new String(new byte[92003849]); // --> Exception
JDK Version: 1.4.2_06
OS: Windows XP
Is this a known bug / limitation? I found a similar bug related to Java on Linux / Solaris, but this one was about getBytes() with Strings > 16MB.
Thanks for your help!Is there any alternative to solve this problem.I am getting the error
java.nio.BufferOverflowException .This happens in my mail server when the file six\ze of xml where i have stored data about spam/nonspam grows upto 22mb.I have stored this xml in database as blob.at server startup uploading in in my class.Keeps througout in JVM after every 50 th request saving information back to database(about spam/nonspam).Now if xml size grows i am storing this in string to parse etc.it gives this bug error.Sholud i cahnge my datatype or use something as XML Parser to split my xml in pieces(mechanism i am not aware of at all) so that string just takes some size of xml (but here can i use string builder etc.). Now is there any proper solution to this kind of problem whenever i removes some daya from xml spam mail goes to inbox and vice versa.
Please suggest me some solution if possible.
complete error is:
Servlet initialization failed:
java.nio.BufferOverflowException
at java.nio.charset.CoderResult.throwException(CoderResult.java:259)
at java.lang.StringCoding$CharsetSD.decode([BII)[C(Unknown Source)
at java.lang.StringCoding.decode(Ljava.lang.String;[BII)[C(Unknown Source)
at java.lang.String.<init>([BIILjava.lang.String;)V(Unknown Source)
at java.lang.String.<init>([BLjava.lang.String;)V(Unknown Source)
at zerocode.core.ByteBlock.toString(ByteBlock.java:89)
at zcCollab.mailProcessing.NaiveBayesClassifier._getInstanceData(NaiveBayesClassifier.java:275)
at zcCollab.mailProcessing.NaiveBayesClassifier.initialize(NaiveBayesClassifier.java:86)
at zcCollab.mailProcessing.SimpleDeliveryManager._setupClassifiers(SimpleDeliveryManager.java:409)
at zcCollab.mailProcessing.SimpleDeliveryManager.<init>(SimpleDeliveryManager.java:62)
at zcCollab.zcApp.InfoManagerApp._createDeliveryProcessor(InfoManagerApp.java:307)
at zcCollab.zcApp.InfoManagerApp.initialize(InfoManagerApp.java:294)
at zerocode.udm.Application._createInstance(Application.java:168)
at zerocode.udm.Application.createInstanceForServlet(Application.java:111)
at zerocode.servlet.UdmServlet._createApplication(UdmServlet.java:67)
at zerocode.servlet.UdmServlet._initialize(UdmServlet.java:52)
at zerocode.servlet.GenericServlet.init(GenericServlet.java:116)
at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:292)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:329)
at org.mortbay.jetty.servlet.ServletHandler.dispatch(ServletHandler.java:657)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:567)
at org.mortbay.http.HttpContext.handle(HttpContext.java:1808)
at org.mortbay.http.HttpContext.handle(HttpContext.java:1758)
at org.mortbay.http.HttpServer.service(HttpServer.java:879)
at org.mortbay.http.handler.ForwardHandler.handle(ForwardHandler.java:130)
at org.mortbay.http.HttpContext.handle(HttpContext.java:1808)
at org.mortbay.http.HttpContext.handle(HttpContext.java:1758)
at org.mortbay.http.HttpServer.service(HttpServer.java:879)
Thanks
Vijendra -
Javac compiler throws java.nio.BufferOverflowException!!Why?
An exception has occurred in the compiler (1.4.1). Please file a bug at the Java Developer Connection (http://java.sun.com/cgi-bin/bugreport.cgi) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.nio.BufferOverflowException
at java.nio.charset.CoderResult.throwException(CoderResult.java:259)
at java.lang.StringCoding$CharsetSD.decode(StringCoding.java:186)
at java.lang.StringCoding.decode(StringCoding.java:222)
at java.lang.StringCoding.decode(StringCoding.java:228)
at java.lang.String.<init>(String.java:383)
at java.lang.String.<init>(String.java:404)
at java.io.UnixFileSystem.list(Native Method)
at java.io.File.list(File.java:914)
at com.sun.tools.javac.v8.code.ClassReader.list(ClassReader.java:1224)
at com.sun.tools.javac.v8.code.ClassReader.listAll(ClassReader.java:1320)
at com.sun.tools.javac.v8.code.ClassReader.fillIn(ClassReader.java:1340)
at com.sun.tools.javac.v8.code.ClassReader.complete(ClassReader.java:1049)
at com.sun.tools.javac.v8.code.Symbol.complete(Symbol.java:332)
at com.sun.tools.javac.v8.comp.Enter.visitTopLevel(Enter.java:467)
at com.sun.tools.javac.v8.tree.Tree$TopLevel.accept(Tree.java:390)
at com.sun.tools.javac.v8.comp.Enter.classEnter(Enter.java:442)
at com.sun.tools.javac.v8.comp.Enter.classEnter(Enter.java:456)
at com.sun.tools.javac.v8.comp.Enter.complete(Enter.java:588)
at com.sun.tools.javac.v8.comp.Enter.main(Enter.java:574)
at com.sun.tools.javac.v8.JavaCompiler.compile(JavaCompiler.java:334)
at com.sun.tools.javac.v8.Main.compile(Main.java:520)
at com.sun.tools.javac.Main.compile(Main.java:36)
at com.sun.tools.javac.Main.main(Main.java:27)See this bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4949631 -
Why String.getBytes() throws BufferOverflowException exception?
the following is my codes:
String gbStr = new String(s_content.getBytes(),"ISO_8859_1");
but sometimes it throws exception like this:
java.nio.BufferOverflowException
at java.nio.charset.CoderResult.throwException(CoderResult.java:259)
at java.lang.StringCoding$CharsetSE.encode(StringCoding.java:338)
at java.lang.StringCoding.encode(StringCoding.java:372)
at java.lang.StringCoding.encode(StringCoding.java:378)
at java.lang.String.getBytes(String.java:608)
why?One explaination offered is
We took a look at the source code of the JVM. The
problem stems from the fact that float values are used
to indicate the maximum value of bytes per characters
in java.nio.charset.CharsetEncoder.maxBytesPerChar.
The issue is that floats cannot accuratly hold more than
2^24 integer values which is equals to 16,777,216.
After that value is reached, the encoding operation in
the character set classes incorrectly rounds down the
amount of memory needed for the buffer. The correct
solution would be to use doubles instead, or account
for the round off problem by increasing the buffer size.
SUGGESTED WORKAROUND
The workaround that we are using, is to use to .
getBytes() on a substring that is smaller than 16MB,
and combined the results by either using a
ByteArrayOutputStream or a ByteBuffer.
NOTE: If you are planning on using more than one-byte
characters sets, than you have to make sure that your
buffer is set accordingly. -
How to put a String into a byte array
How can i put a String into a byte array byte[]. So that i can send it to the serial port for output to an LCD display. Cheers David
javadocs for String
getBytes
public byte[] getBytes()
Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.
Returns:
The resultant byte arraySince:
JDK1.1 -
how do you replace something like this? even if you go through characters, the deprecations notes say that goin through character arrays is wrong, right? if you just use String.getBytes() then you get them all and you can specify the parts you want...any ideas?
so far i have this:
tmp = newData.getBytes();
for (int t=0;t<toCopy;t++) {
buffer[offset + t] = tmp[t];
seems klunky... -
How to encode a string to base64 in java ?
Hi, I want to send my user name to my SMTP server encoded in base64 .
How do I do this ??
RameshOk I wait for you.
I guess the following covert a string to base 8
String userName ="Ramesh"
byte[] strBytes = userName.getBytes("UTF-8");
I do not know about base64.
I need this urgently because I am sending my user name and password to my SMTP server and they should be encoded in base64.
Please help.
Ramesh -
Help with Sample on Converting an XML string to a byte stream
Hello All,<br /><br />I am sure this is something simple, but I am just not figuring it out right now.<br /><br />I am following the sample - "Converting an XML string to a byte stream" from the developer guide since I want to prepopulate just 1 field in my PDF form.<br /><br />How do I reference my form field within my servlet code properly??<br /><br />I have tried a few things now, my field is within a subform, so I thought it would be <root><subformName><fieldname>My data</fieldname></subformName></root> I have also tried adding <page1> in there too.<br /><br />I am following everything else exactly as given in the sample code.<br /><br />I do have an embedded schema within the form and the field is bound.<br /><br />Thanks,<br />Jennifer
Well, if you have a schema defined in the form, then the hierarchy of your data must match what is described in the schema. So, can't really tell you what it would look like, but just follow your schema.
Chris
Adobe Enterprise Developer Support -
I periodically get a stuck Execute thread on my Weblogic 8.15 server
during a call to a Stateless Session Bean. When I do thread dumps, the
thread is always stuck in the same place (in
java.lang.String.equals(String.java:619) or in the call immediately above it
java.util.LinkedList.indexOf(LinkedList.java:397)). Even though the thread
dump indicates that the thread is in a runnable state, if I do multiple
thread dumps over a period of time, the stack trace always indicates that
the thread is in the same place. The thread remains stuck until Weblogic is
restarted. Other client applictions can make session bean calls, but each
stuck thread seems to still take up lots of CPU time. I have let the stuck
threads run overnight, and the stack trace from the thread dump always shows
them executing the same String/LinkedList code. In each case, our code is
trying to iterate over a collection
Does anybody know what could cause this problem, and how to fix it? I get
StuckThreadMaxTime errors in the log:
####<Dec 4, 2005 10:47:25 AM EST> <Error> <WebLogicServer> <nybill>
<myserver> <weblogic.health.CoreHealthMonitor> <<WLS Kernel>> <>
<BEA-000337> <ExecuteThread: '4' for queue: 'weblogic.kernel.Default' has
been busy for "1,263" seconds working on the request
"ncss.billing.ejb.billAdmin.session.BillAdminSession_uli3xb_EOImpl", which
is more than the configured time (StuckThreadMaxTime) of "1,200" seconds.>
Here are some stack traces from different thread dumps (I have the full
thread dumps if necessary):
"ExecuteThread: '10' for queue: 'weblogic.kernel.Default'" daemon prio=5
tid=0x7720eb98 nid=0xd68 runnable [571f000..571fdb0]
at java.lang.String.equals(String.java:619)
at java.util.LinkedList.indexOf(LinkedList.java:398)
at java.util.LinkedList.contains(LinkedList.java:176)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getDailyCallSummary(XMLBillCr
eation.java:1992)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getGraphs(XMLBillCreation.jav
a:1931)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getLocations(XMLBillCreation.
java:2618)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.createXMLBill(XMLBillCreation
.java:236)
at
ncss.billing.ejb.billAdmin.session.BillAdminSessionEJB.getBillAsXml(BillAdmi
nSessionEJB.java:341)
at
ncss.billing.ejb.billAdmin.session.BillAdminSession_uli3xb_EOImpl.getBillAsX
ml(BillAdminSession_uli3xb_EOImpl.java:100)
at
ncss.billing.ejb.billAdmin.session.BillAdminSession_uli3xb_EOImpl_WLSkel.inv
oke(Unknown Source)
at
weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:477)
at
weblogic.rmi.cluster.ReplicaAwareServerRef.invoke(ReplicaAwareServerRef.java
:108)
at
weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:420)
at
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubjec
t.java:363)
at
weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147)
at
weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:415)
at
weblogic.rmi.internal.BasicExecuteRequest.execute(BasicExecuteRequest.java:3
0)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:219)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:178)
"ExecuteThread: '22' for queue: 'weblogic.kernel.Default'" daemon prio=5
tid=0x772538d0 nid=0xe24 runnable [497f000..4fdb0]
at java.lang.String.equals(String.java:619)
at java.util.LinkedList.indexOf(LinkedList.java:398)
at java.util.LinkedList.contains(LinkedList.java:176)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getMostExpensiveOrLongestCall
s(XMLBillCreation.java:1892)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getTopTenReport(XMLBillCreati
on.java:1798)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getTopTenReports(XMLBillCreat
ion.java:1751)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getLocations(XMLBillCreation.
java:2612)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.createXMLBill(XMLBillCreation
.java:236)
at
ncss.billing.ejb.billAdmin.session.BillAdminSessionEJB.getBillAsXml(BillAdmi
nSessionEJB.java:341)
at
ncss.billing.ejb.billAdmin.session.BillAdminSession_uli3xb_EOImpl.getBillAsX
ml(BillAdminSession_uli3xb_EOIm.java:100)
at
ncss.billing.ejb.billAdmin.session.BillAdminSession_uli3xb_EOImpl_WLSkel.inv
oke(Unknown Source)
at
weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:477)
at
weblogic.rmi.cluster.ReplicaAwareServerRef.invoke(ReplicaAwareServerRef.java
:108)
at
weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:420)
at
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubjec
t.java:363)
at
weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147)
at
weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:415)
at
weblogic.rmi.internal.BasicExecuteRequest.execute(BasicExecuteRequest.java:3
0)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:219)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:178)
"ExecuteThread: '21' for queue: 'weblogic.kernel.Default'" daemon prio=5
tid=0x76afb060 nid=0x498 runnable [48af000..48fdb0]
at java.lang.String.equals(String.java:619)
at java.util.LinkedList.indexOf(LinkedList.java:398)
at java.util.LinkedList.contains(LinkedList.java:176)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getMostFrequentlyCalledNumber
sOrCitiesReport(XMLBillCreation.java:1839)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getTopTenReport(XMLBillCreati
on.java:1772)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getTopTenReports(XMLBillCreat
ion.java:1743)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.getLocations(XMLBillCreation.
java:2612)
at
ncss.billing.broadviewBill.xml.XMLBillCreation.createXMLBill(XMLBillCreation
.java:236)
at
ncss.billing.ejb.billAdmin.session.BillAdminSessionEJB.getBillAsXml(BillAdmi
nSessionEJB.java:341)
at
ncss.billing.ejb.billAdmin.session.BillAdminSession_uli3xb_EOImpl.getBillAsX
ml(BillAdminSession_uli3xb_EOImp.java:100)
at
ncss.billing.ejb.billAdmin.session.BillAdminSession_uli3xb_EOImpl_WLSkel.inv
oke(Unknown Source)
at
weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:477)
at
weblogic.rmi.cluster.ReplicaAwareServerRef.invoke(ReplicaAwareServerRef.java
:108)
at
weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:420)
at
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubjec
t.java:363)
at
weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147)
at
weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:415)
at
weblogic.rmi.internal.BasicExecuteRequest.execute(BasicExecuteRequest.java:3
0)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:219)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:178)
The code in LinkedList that it seems to be executing is the following:
Line#
397 for (Entry e = header.next; e != header; e = e.next) {
398 if (o.equals(e.element))
399 return index;
400 index++;
401 }
I am running Weblogic 8.15 on Windows 2000.
Thanks for any help,
- Donnjb7ty wrote:
I suggest dropping that example program and concentrating on reading a book on Java such as 'Head First in Java'. Otherwise, you will spend a lot of time trying to get something to work and gain little value from it.Likewise... Jumping into reflections before you can [read a stack-trace|http://www.0xcafefeed.com/2004/06/of-thread-dumps-and-stack-traces/] is like signing up a toddler for the New York Marathon... it's probably simply beyond your skill level... so step back... go read a book, do some tutorials, get your head around just the process of the designing, writing, compiling, running, and debugging java programs... and what the different diagnostics mean... Then, equipped with your nose-clip and your trusty stone ;-) you contemplate leaping into the deep end ;-)
Cheers. Keith. -
How can I pass a String by reference in java?
Hello!
My question is how to pass a String by reference in java.
I tried to declare my variable, instead of using "String xxx = "f";", I used "String xxx = new String ("f");" :
public static void main (String []args)
String xxx = new String("f");
StatusEnum result2 = getErrorPointStr(xxx);
public StatusEnum getErrorPointStr(String text)
StatusEnum testStatus = StatusEnum.PASS;
StringBuffer buffer = new StringBuffer();
buffer.append("123");
text = buffer.toString();
return testStatus;
After calling to getErrorPointStr(String text) function, xxx = "f"
So it does not work.
How can I solve this? It is very important, the function will receive String and not something else.
Thanks!Tolls wrote:
Which is why I said:
Which is why you only managed to change what 'text' referred to in the methodExcept that's not why. Even if String was mutable, doing text = whatever; would have the same effect; it would change what that variable refers to in the method, but it would not change the object's state.
I meant that, since there was no way to actually change the data (ie the char[] or whatever) within the object 'text' referred to, the OP was attempting to change what 'text' referred to and hoping it would be reflected outside the method...which we know won't happen as Java is pass-by-value.\Ah, now I see.
These by-value/by-reference threads tend to get confusing, because usually the person is passing a String, so the immutability of String tends to get in the way and just muddy the waters. -
Accessing String variables from several JAVA classes
Hi.
I have several java classes that accesses the same String variables. Instead of putting the String declarations in every java files, how can I put these declarations in a single file source, and get each java class to get the variables data from this file ?
Please advice.
Thanks.hi, of course you can solve it by the following methods:
Method 1. define a superclass including the common string variable, and extend other classes from the superclass.
Method 2. define a class , and define your common string variable as a static variable in it. In your other classes, you can call the string variable.
Method 3. define it at your each classes. -
Como obtener un array dbl de un string de 2 bytes
como obtener un array dbl de un string de 2 bytes
Adjuntos:
dbl.png 37 KBHola, un string de dos bytes no puede contener un double ya que el dbl es un número de 8 bytes.
Acaso estás recibiendo alguna medicion de un conversor de 16 bits (un instrumento externo, un PIC o algo así)? Si es así el valor correspondiente en la unidad de medición (V, A, RPM...) debe calcularse con
bits recibidos / 65536 * máximo de la medición
Ejemplo: en un voltímetro de 100V / 16 bits, un valor de 8000 (bits) equivale a una medición de 12.207V
Proud to use LW/CVI from 3.1 on.
My contributions to the Developer Zone Community
If I have helped you, why not giving me a kudos? -
I need to make the server is able to hold about 500 connections and operates on a single thread. The server itself should make all the connections. Where can I find examples of finished implementations?
I have an example, but it does not work
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.*;
public class NioClient implements Runnable {
// The host:port combination to connect to
private InetAddress hostAddress;
private String host;
private int port;
// The selector we'll be monitoring
private Selector selector;
// The buffer into which we'll read data when it's available
private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
// A list of PendingChange instances
private List pendingChanges = new LinkedList();
// Maps a SocketChannel to a list of ByteBuffer instances
private Map pendingData = new HashMap();
// Maps a SocketChannel to a RspHandler
private Map rspHandlers = Collections.synchronizedMap(new HashMap());
public NioClient() {
try {this.selector = this.initSelector();} catch(IOException e){}
public void connect(String host, int port, RspHandler handler) throws IOException {
this.hostAddress = hostAddress;
this.host = host;
this.port = port;
this.send("$Hello |".getBytes(), handler);
public void send(byte[] data, RspHandler handler) throws IOException {
// Start a new connection
SocketChannel socket = this.initiateConnection();
// Register the response handler
this.rspHandlers.put(socket, handler);
// And queue the data we want written
synchronized (this.pendingData) {
List queue = (List) this.pendingData.get(socket);
if (queue == null) {
queue = new ArrayList();
this.pendingData.put(socket, queue);
queue.add(ByteBuffer.wrap(data));
// Finally, wake up our selecting thread so it can make the required changes
this.selector.wakeup();
handler.waitForResponse();
public void run() {
while (true) {
try {
// Process any pending changes
synchronized (this.pendingChanges) {
Iterator changes = this.pendingChanges.iterator();
while (changes.hasNext()) {
ChangeRequest change = (ChangeRequest) changes.next();
switch (change.type) {
case ChangeRequest.CHANGEOPS:
SelectionKey key = change.socket.keyFor(this.selector);
key.interestOps(change.ops);
break;
case ChangeRequest.REGISTER:
change.socket.register(this.selector, change.ops);
break;
this.pendingChanges.clear();
// Wait for an event one of the registered channels
this.selector.select();
// Iterate over the set of keys for which events are available
Iterator selectedKeys = this.selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
SelectionKey key = (SelectionKey) selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
// Check what event is available and deal with it
if (key.isConnectable()) {
this.finishConnection(key);
} else if (key.isReadable()) {
this.read(key);
} else if (key.isWritable()) {
this.write(key);
} catch (Exception e) {
e.printStackTrace();
private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
// Clear out our read buffer so it's ready for new data
this.readBuffer.clear();
// Attempt to read off the channel
int numRead;
try {
numRead = socketChannel.read(this.readBuffer);
} catch (IOException e) {
// The remote forcibly closed the connection, cancel
// the selection key and close the channel.
key.cancel();
socketChannel.close();
return;
System.out.println("READ");
if (numRead == -1) {
// Remote entity shut the socket down cleanly. Do the
// same from our end and cancel the channel.
key.channel().close();
key.cancel();
return;
// Handle the response
this.handleResponse(socketChannel, this.readBuffer.array(), numRead);
private void handleResponse(SocketChannel socketChannel, byte[] data, int numRead) throws IOException {
// Make a correctly sized copy of the data before handing it
// to the client
byte[] rspData = new byte[numRead];
System.arraycopy(data, 0, rspData, 0, numRead);
// Look up the handler for this channel
RspHandler handler = (RspHandler) this.rspHandlers.get(socketChannel);
// And pass the response to it
if (handler.handleResponse(rspData)) {
// The handler has seen enough, close the connection
socketChannel.close();
socketChannel.keyFor(this.selector).cancel();
private void write(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
synchronized (this.pendingData) {
List queue = (List) this.pendingData.get(socketChannel);
// Write until there's not more data ...
while (!queue.isEmpty()) {
ByteBuffer buf = (ByteBuffer) queue.get(0);
socketChannel.write(buf);
if (buf.remaining() > 0) {
// ... or the socket's buffer fills up
break;
queue.remove(0);
if (queue.isEmpty()) {
// We wrote away all data, so we're no longer interested
// in writing on this socket. Switch back to waiting for
// data.
key.interestOps(SelectionKey.OP_READ);
private void finishConnection(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
// Finish the connection. If the connection operation failed
// this will raise an IOException.
try {
socketChannel.finishConnect();
} catch (IOException e) {
// Cancel the channel's registration with our selector
System.out.println(e);
key.cancel();
return;
// Register an interest in writing on this channel
key.interestOps(SelectionKey.OP_WRITE);
private SocketChannel initiateConnection() throws IOException {
// Create a non-blocking socket channel
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
// Kick off connection establishment
socketChannel.connect(new InetSocketAddress(this.host, this.port));
// Queue a channel registration since the caller is not the
// selecting thread. As part of the registration we'll register
// an interest in connection events. These are raised when a channel
// is ready to complete connection establishment.
synchronized(this.pendingChanges) {
this.pendingChanges.add(new ChangeRequest(socketChannel, ChangeRequest.REGISTER, SelectionKey.OP_CONNECT));
return socketChannel;
private Selector initSelector() throws IOException {
// Create a new selector
return SelectorProvider.provider().openSelector();
public class RspHandler {
private byte[] rsp = null;
public synchronized boolean handleResponse(byte[] rsp) {
this.rsp = rsp;
this.notify();
return true;
public synchronized void waitForResponse() {
while(this.rsp == null) {
try {
this.wait();
} catch (InterruptedException e) {
System.out.println(new String(this.rsp));
} NioClient NioClient = new NioClient();
Thread t = new Thread(NioClient);
t.setDaemon(true);
t.start();
RspHandler handler = new RspHandler();
NioClient.connect("69.28.156.250", 27040, handler);
NioClient.connect("72.165.61.188", 27040, handler);
NioClient.connect("208.111.133.84", 27011, handler);
NioClient.connect("72.165.61.136", 27012, handler);
Edited by: 915967 on 01.08.2012 7:07 -
Java.nio select() method return 0 in my client application
Hello,
I'm developing a simple chat application who echo messages
But my client application loop because the select() method return 0
This is my code
// SERVER
package test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class Server {
private int port = 5001;
public void work() {
try {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
InetSocketAddress isa = new InetSocketAddress(port);
serverSocketChannel.socket().bind(isa);
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Listing on "+port);
while(selector.select()>0) {
Set keys = selector.selectedKeys();
for(Iterator i = keys.iterator(); i.hasNext();) {
SelectionKey key = (SelectionKey) i.next();
i.remove();
if (key.isAcceptable()) {
ServerSocketChannel keyChannel = (ServerSocketChannel)key.channel();
SocketChannel channel = keyChannel.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ );
} else if (key.isReadable()) {
SocketChannel keyChannel = (SocketChannel) key.channel();
String m = Help.read(keyChannel );
Help.write(m.toUpperCase(), keyChannel );
} catch (IOException e) {
e.printStackTrace();
public static void main(String[] args) {
Server s = new Server();
s.work();
// CLIENT
package test;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Client extends JFrame {
private String host = "localhost";
private int port = 5001;
private SocketChannel socketChannel;
private Selector selector;
public void work() {
try {
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
InetSocketAddress isa = new InetSocketAddress(host, port);
socketChannel.connect(isa);
selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ );
while(true) {
selector.select();
Set keys = selector.selectedKeys();
for(Iterator i = keys.iterator(); i.hasNext();) {
SelectionKey key = (SelectionKey) i.next();
i.remove();
if (key.isConnectable()) {
SocketChannel keyChannel = (SocketChannel) key.channel();
if (keyChannel.isConnectionPending()) {
System.out.println("Connected "+keyChannel.finishConnect());
} else if (key.isReadable()) {
SocketChannel keyChannel = (SocketChannel) key.channel();
String m = Help.read(keyChannel);
display(m);
} catch (IOException e) {
e.printStackTrace();
private void display(final String m) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
area.append(m+"\n");
textFieed.setText("");
private void sendMessage(final String m) {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Help.write(m, socketChannel);
} catch (IOException e) {
e.printStackTrace();
t.start();
public Client() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(1);
textFieed.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()== KeyEvent.VK_ENTER) {
String m = textFieed.getText();
sendMessage(m);
area.setEditable(false);
getContentPane().add(textFieed, "North");
getContentPane().add(new JScrollPane(area));
setBounds(200, 200, 400, 300);
show();
private String messageToSend;
private JTextArea area = new JTextArea();
JTextField textFieed = new JTextField();
public static void main(String[] args) {
Client s = new Client();
s.work();
// HELPER CLASS
package test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
public class Help {
private static Charset charset = Charset.forName("us-ascii");
private static CharsetEncoder enc = charset.newEncoder();
private static CharsetDecoder dec = charset.newDecoder();
private static void log(String m) {
System.out.println(m);
public static String read(SocketChannel channel) throws IOException {
log("*** start READ");
int n;
ByteBuffer buffer = ByteBuffer.allocate(1024);
while((n = channel.read(buffer)) > 0) {
System.out.println(" adding "+n+" bytes");
log(" BUFFER REMPLI : "+buffer);
buffer.flip();
CharBuffer cb = dec.decode(buffer);
log(" CHARBUFFER : "+cb);
String m = cb.toString();
log(" MESSAGE : "+m);
log("*** end READ");
//buffer.clear();
return m;
public static void write(String m, SocketChannel channel) throws IOException {
log("xxx start WRITE");
CharBuffer cb = CharBuffer.wrap(m);
log(" CHARBUFFER : "+cb);
ByteBuffer buffer = enc.encode(cb);
log(" BUFFER ALLOUE REMPLI : "+buffer);
int n;
while(buffer.hasRemaining()) {
n = channel.write(buffer);
System.out.println(" REMAINING : "+buffer.hasRemaining());
log("xxx end WRITE");Here's the fix for that old problem. Change the work method to do the following
- don't register interest in things that can't happen
- when you connect register based on whether the connection is complete or pending.
- add the OP_READ interest once the connection is complete.
This doesn't fix all the other problems this code will have,
eg.
- what happens if a write is incomplete?
- why does my code loop if I add OP_WRITE interest?
- why does my interestOps or register method block?
For code that answers all those questions see my obese post Taming the NIO Circus
Here's the fixed up Client code
// CLIENT
package test
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Client extends JFrame {
private String host = "localhost";
private int port = 5001;
private SocketChannel socketChannel;
private Selector selector;
public void work() {
try {
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
InetSocketAddress isa = new InetSocketAddress(host, port);
socketChannel.connect(isa);
selector = Selector.open();
int interest = 0;
if(socketChannel.isConnected())interest = SelectionKey.OP_READ;
else if(socketChannel.isConnectionPending())interest = SelectionKey.OP_CONNECT;
socketChannel.register(selector, interest);
while(true)
int nn = selector.select();
System.out.println("nn="+nn);
Set keys = selector.selectedKeys();
for(Iterator i = keys.iterator(); i.hasNext();)
SelectionKey key = (SelectionKey) i.next();
i.remove();
if (key.isConnectable())
SocketChannel keyChannel = (SocketChannel) key.channel();
System.out.println("Connected "+keyChannel.finishConnect());
key.interestOps(SelectionKey.OP_READ);
if (key.isReadable())
SocketChannel keyChannel = (SocketChannel) key.channel();
String m = Help.read(keyChannel);
display(m);
} catch (IOException e) {
e.printStackTrace();
private void display(final String m) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
area.append(m+"\n");
textFieed.setText("");
private void sendMessage(final String m) {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Help.write(m, socketChannel);
} catch (IOException e) {
e.printStackTrace();
t.start();
public Client() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(1);
textFieed.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()== KeyEvent.VK_ENTER) {
String m = textFieed.getText();
sendMessage(m);
area.setEditable(false);
getContentPane().add(textFieed, "North");
getContentPane().add(new JScrollPane(area));
setBounds(200, 200, 400, 300);
show();
private String messageToSend;
private JTextArea area = new JTextArea();
JTextField textFieed = new JTextField();
public static void main(String[] args) {
Client s = new Client();
s.work(); -
ByteArray to String and String to ByteArray error at readUTF from datainpu
hi everybody this is my first post I hope I can find the help I need I have been doing some research and couldnt find the solution thanks in advanced
The Objective:
im building a client server application with java and I need to send a response from the server to the client via Socket
so the response is like this : <Signal : ByteArray> where Signal is a String so the client can Identify the Type of response
and the ByteArray is an Array of bytes containing the Information I need
The Problem:
I have an Array of bytes containing the info to send and I need to pass this byte[] to a String add some String that let me Identify the data in the client side then remove the identifier in the client side and convert the resulting String back to an array of bytes this doesnt work
The Code:
Server Side (Creating the Byte Array):
public byte[] createData(){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeUTF(requestedFile.getName());
dos.flush();
byte[] data = baos.toByteArray();
return data;
}Server Side (Converting the byte[] to String and Add some Identifier)
byte[] data= createData(); //Obtain the data in a byte[]
String response = new String(data); //Convert the Data to String
String Identifier= "14"; // to identify in the client side the data received this will be removed later
response = Identifier+response; // add the identifier to the String
sendToClient( response.getBytes() ); //obtain bytes from the complete Response and send them to clientClient Side ( Receive the response that is a byte array containing the identifier plus the info <Identifier : info> )
int index=response.indexOf(":")+1; //find the index of the : so i can delete the identifier
response=response.substring(index); // delete the identifier
byte[] data = response.getBytes(); // obtains the bytes for the info ONLY cause the string no longer has identif
receiveData ( data ); // send the data to be read by this method Client Side (Receive the Info sent from the server and read it)
public void receiveData ( byte[] data ) {
ByteArrayInputStream bais = new ByteArrayInputStream ( data );
DataInputStream dis= new DataInputStream ( bais );
setTotalSize ( dis.readUTF( ) ); // here is the error it catches an EndOfFileException without read the info
}im tried sending other values like long and int and i was able to read them but the problem is with the Strings at the ReadUTF()
Im tried to be the most clear as possible please help me this is driving me nuts
and I would really appreciatte all your comments thankslemaniak wrote:
The Objective:
im building a client server application with java and I need to send a response from the server to the client via Socket
so the response is like this : <Signal : ByteArray> where Signal is a String so the client can Identify the Type of response
and the ByteArray is an Array of bytes containing the Information I need
The Problem:
I have an Array of bytes containing the info to send and I need to pass this byte[] to a String add some String that let me Identify the data in the client side then remove the identifier in the client side and convert the resulting String back to an array of bytes this doesnt workFirst of all, well done: a nicely explained problem. I wish more people were as clear as you.
Second: I'm no expert on this stuff, so I may well be wrong, but I did note the following:
1. I can't see anywhere where you're putting out the ":" to separate your signal.
2. You seem to be doing an awful lot of conversions from Strings to bytes and vice-versa, but only your filename is specified as a UTF-8 conversion. Could you not do something like:
dos.writeUTF("14:" + requestedFile.getName());or indeed, more generically
dos.writeUTF(signal + ":" + messageBody);from inside a createMessage() method.
3. You haven't included the sendToClient() code, but your createData() looks suspiciously like what I would put in a method like that.
From what I understand, you usually want mirror-images of your streams at your sending and receiving ends, so if your client is expecting an DataInputStream wrapping a ByteArrayInputStream to be read via readUTF(), your server better be sending a ByteArrayOutputStream wrapped in a DataOutputStream created, in its entirety, by writeUTF().
But after your UTF conversion, you're adding your signal and then using String.getBytes(), which uses the default character set, not UTF.
HIH (and hope I'm right :-))
Winston
Maybe you are looking for
-
Outlook: "Send Immediately when connected" not working for Word 2010
When i disable the option in Outlook "Send Immediately when connected" the messages are placed in the Outbox until i send them manually. But when i want to send a Word 2010 document from within Word 2010 by E-Mail the message is send immediately. Is
-
Error while check printing through f-58
Error while check printing through f-58 is showing following for company code xxxx 1. Fiscal year variant z4 not defined or maintained for date 01/06/08 . (Fiscal year variant Z4 not defined or maintained for date 01/09/2009 Message no. GMMASTERDATA
-
Disk Utility - FIX PERMISSIONS
When i try and fix permissions it just hangs saying it will be done in one minute....I tried it at the apple store on their macs and had the same problem on multiple machines...Any thoughts on what the deal is here?
-
Video and Audio with 1 second delay
I am editing on a MAC with Premiere Pro Cs6, 6.01(014 (MC:264587)) a 45 minute file from an Ipad 3, 720. The origina file is synchronized perfectly, you can play withe Quicktime viewer and the lips move with the audio. After using that single file on
-
Shopping Cart Error: Buffer Table not up to date
Hi All, We are getting a short dump with following error when some users are clicking on 'Shop' option:- We have checked the org attributes, user attributes and roles, but they look fine. Please help. <The following error text was processed in the sy