Re: WebSocket
On 18/02/18 20:12, Chuck Davis wrote: ... RESULT: The formerly fabulous WebSocket has been rendered relatively useless as a platform for building responsive, bidirectional client/server applications. Am I the only person who sees this as a HUGE regression of functionality?? I am ALARMED by this turn of events. A point of clarification that may, or may not, be obvious to readers of this thread. The WebSocket API, with JDK 8, that is being compared is the Java EE API for WebSocket [1]. It is completely orthogonal to the proposed Java SE WebSocket API. Users of said API can continue to use it, if it meets their needs. Nothing being proposed here has any impact on it. The Java EE API for WebSocket provides higher-level API abstractions for handling whole and partial messages, decoding and encoding, etc. The proposed Java SE WebSocket API is a less-verbose, lower-level, API. They are two separate and distinct APIs. If one desires the the higher-level abstractions provided by the EE API, that is absolutely fine. The SE WebSocket API is not a replacement for the EE API, it is a lower-level alternative with simpler abstractions. A consequence of its simplicity is that a developer may need to do more to handle the data, but in many cases this is exactly what it wanted. These APIs complement each other rather than compete. -Chris [1] https://docs.oracle.com/javaee/7/api/javax/websocket/package-summary.html
Re: WebSocket
Hi Chris and others: There is only one WebSocket documented in jdk9. I was happy to be able to write a jdk9 client that connected to my server unchanged (using Wildfly11). And there are features of jdk9 API that I rather like. There are two vastly differing handling requirements. I certainly am not smart enough to figure out how to handle both in the same implementation. With all credit to James the need to send Java objects over a wire is not going to go away anytime soon. But deserialization cannot commence until the entire payload generated by the ObjectOutputStream is in a single buffer at the destination (whether client or server). Let's call this the buffer processing approach. Then you have the crowd who need to process a stream of music, video or you name it. In that case you want the jdk9 approach to process smaller bits of the stream as they arrive. Let's call this the stream processing approach. While both approaches are streams the streams are so vastly different I don't see any way to process them both with a single API implementation. But as I said, I am not the sharpest knife in the drawer and maybe you guys have the smarts to pull it off. I certainly hope so. The current jdk9 implementation is not suitable for data-driven applications that have to process a buffer. Putting all the pieces back together is prohibitively expensive in time and resources. For those who need to process a stream the jdk9 implementation appears to be a great leap forward. I maintain we need both. On Mon, Feb 19, 2018 at 3:45 AM, Chris Hegarty wrote: > > On 18/02/18 20:12, Chuck Davis wrote: > >> ... >> >> RESULT: The formerly fabulous WebSocket has been rendered relatively >> useless as a platform for building responsive, bidirectional >> client/server applications. Am I the only person who sees this as a >> HUGE regression of functionality?? I am ALARMED by this turn of >> events. >> > > A point of clarification that may, or may not, be obvious > to readers of this thread. > > The WebSocket API, with JDK 8, that is being compared is the > Java EE API for WebSocket [1]. It is completely orthogonal to > the proposed Java SE WebSocket API. Users of said API can > continue to use it, if it meets their needs. Nothing being > proposed here has any impact on it. > > The Java EE API for WebSocket provides higher-level API > abstractions for handling whole and partial messages, decoding > and encoding, etc. The proposed Java SE WebSocket API is a > less-verbose, lower-level, API. They are two separate and > distinct APIs. If one desires the the higher-level abstractions > provided by the EE API, that is absolutely fine. > > The SE WebSocket API is not a replacement for the EE API, it > is a lower-level alternative with simpler abstractions. A > consequence of its simplicity is that a developer may need > to do more to handle the data, but in many cases this is > exactly what it wanted. These APIs complement each other > rather than compete. > > -Chris > > [1] https://docs.oracle.com/javaee/7/api/javax/websocket/package > -summary.html >
Re: WebSocket
Further thought... Maybe a single WebSocket but two different listeners the developer can choose depending upon what type of stream is expected???
Re: WebSocket
Hi, On Sun, Feb 18, 2018 at 9:12 PM, Chuck Davis wrote: > There is a great hush here regarding strategy for putting the pieces > back together so here goes my tirade. > > Following is based on assumption of a 100k payload. > > With jdk8: > The decoder received a ByteBuffer > bais = new ByteArrayInputStream(ByteBuffer.array()); // wrap the > buffer -- optional method but implemented in Oracle JVM > ois = new ObjectInputStream(bais) // wrap the input stream > MyDTO = ois.readObject(); // deserialize the object (which may > contain hundreds or thousands of objects) > > DONE! Simple, clean and blazingly fast. Well, not so fast. There are a lot of assumptions in the above code. The first is that the ByteBuffer has a backing array, which may not be the case. If you write the right code that takes care of the possibility that the ByteBuffer does not have a backing array, you end up with another copy and more code. More importantly, the implementation would have done all the copies for you in order to feed your code with a final ByteBuffer. So you are not really skipping the copies and the performance is not different from below, where the possible copies are explicit. > With jdk9: > The Listener receives a ByteBuffer (I read someplace the default size > is potentially going to be 256 bytes) > If it's the first part (or whole) create a byte[] of 10k (or whatever) > Start copying bytes from the buffer to the array > Check each byte to be sure there is room in the array for another byte > if room, copy the byte > if no room, copy the array to a larger array (current size + 10k) > and then copy the byte > repeat until all messages are processed (i.e. each byte will have > been copied somewhere between 1 and 10 times) > bais = new ByteArrayInputStrea(byte[]); > ois = new ObjectInputStream(bais); > MyDTO = ois.readObject(); > > DONE! More complicated, messy and very slow. (i.e. lots of wasted cpu > cycles) Nah :) ByteBufferInputStream bbis = new ByteBufferInputStream(); for each partial ByteBuffer received by the listener { bbis.add(byteBuffer); } ois = new ObjectInputStream(bbis); MyDTO = ois.readObject(); Now, ByteBufferInputStream is not present in the JDK, and if you want to complain you are in good (and conspicuous) company, as the JDK engineers appear to avoid the issue since years now (e.g. create a String from a ByteBuffer without copy). Having said that, the class is trivial to implement (a naive version I wrote is about 30 lines) and may even be provided as a utility class by the JDK WebSocket implementers. The advantage is that ByteBufferInputStream can be written in a way that performs *zero* copies, thanks to the JDK 9 WebSocket APIs - add() would need to return a CompletableFuture. If you don't want to confront with CompletableFutures, it can be written in a way that performs just one copy. > RESULT: The formerly fabulous WebSocket has been rendered relatively > useless as a platform for building responsive, bidirectional > client/server applications. Am I the only person who sees this as a > HUGE regression of functionality?? I am ALARMED by this turn of > events. Nah :) To sum up: * with JDK 9 you need a utility class that you did not need with JDK 8 * with JDK 9 you can actually perform a zero copy provided you put a bit of effort (or the JDK guys do) * with JDK 9 the number of byte copies is the same or better All in all, anything you can do with the JDK 8 API can be done in JDK 9. For some cases, JDK 9 is more efficient than JDK 8. For all other cases it's on par. JDK 9 requires a utility class to convert from ByteBuffer to InputStream. Note also that your requirement is to use blocking, stream-based, byte[]-based APIs. If you had chosen a data format for which a non-blocking parser based on ByteBuffer APIs existed, you would be so happy about the JDK 9 APIs. > OPINION: > > I'm pretty naive about the world of midrange and mainframe except that > they can throw a lot of bytes in a short time. But I imagine the > choke-point of any desktop application is going to be the network. > Unless somebody is running a Pentium I doubt any relatively modern > desktop is going to have a difficult time keeping up with networking > speeds. It seems to me, therefore, that backpressure in WebSocket is > a solution looking for a problem. I have a different experience, where clients may not be able to keep up with the network. This happens with browsers receiving a message and having to update a gazillion DOM nodes (with all the ripple effects that this entails), with clients generating so much garbage that the GC is heavily interfering with their throughput, with proxy applications that have different speeds on the 2 sides they proxy, and so on. Here I am seriously advocating to the net-dev JDK group to provide an efficient solution, or at least start a discussion where appropriate, for ByteBuffer to [Input|Output]Stream that is sorely missing in the JDK. Thanks ! -- Simon
Re: websockets
James (hi! :) On Fri, Feb 16, 2018 at 12:55 AM, James Roper wrote: > The question for me then is whether there is value in introducing an > additional higher level API (ie, a reactive streams based API) for the > purposes of integration with other libraries that provide RS support. I have mixed feeling about this. I first tried to push the WebSocket APIs to be Flow-based when they were slated for JDK 9 official inclusion. As the WebSocket APIs were moved to incubation and are now slated for JDK 11, it may be worth considering again whether it's the case to provide a Flow-based APIs. However, Pavel's point about the limits of the Flow APIs still stand, so a Flow API may be useful, but less generic. Another point that makes me feeling uncertain is the good comment by Konrad Malawski about the design of Akka Streams versus e.g. Spring's Flowable, where the former does not implement RS or Flow interfaces, while the latter does. Now that we have the dichotomy of RS and JDK's Flow, it is easy for Akka Stream implement methods such as asRSPublisher() and asFlowPublisher() so that they work in both environments (with - yuck - multi-release jars). It would be harder for Spring's Flowable to provide support for both RS and Flow. So at the end I would like to see a *separate* Flow API on top of the current WebSocket API, but who's going to implement it ? Would be great to standardize a community effort, but even better if the JDK provided it. > Introducing another API, regardless of what that API is, obviously has > drawbacks as it increases the surface area of the API, and thus complexity, > and also potentially introduces confusion for application developers as they > now have two different ways of achieving things, and they need to know which > to use when. So, the value of that API must be high enough to outweigh those > drawbacks. I strongly believe that a Reactive Streams based API does add > enough value to do that - and the post that I shared in my previous email > demonstrates how an ecosystem where reactive streams is embraced can provide > a lot of value to application developers. So I'm happy to talk more here > about use cases and code samples etc if you don't agree here. I personally don't question the value of a RS or Flow API. It's just a matter of resources - we can ask Oracle to do it, but if they don't have resources to do it, then the road ahead is complicated. I see better a Flow wrapper of the JDK WebSocket APIs under the Reactive Extension (https://github.com/Reactive-Extensions) or Reactive Streams (https://github.com/Reactive-Streams) umbrella. That would perhaps have less resource issues and still give a unique library rather than a gazillion similar wrappers. > For signalling errors upstream, in all the cases that I've worked with, > we've never found a reason that sending the error downstream, and just > cancelling upstream, is a problem. At the end of the day, there is only one > thing that can fail, the TCP connection, and if it fails, both upstream and > downstream will fail - there is no such thing as a half failure in TCP. HttpServlet.service() allows to throw exceptions that the Servlet container must handle by running the error page algorithm, which is user code. A Subscriber (provided by a library) encounters an exception while performing its job. Since it comes from a library, the library itself does not know how to handle the error because it does not know in what environment it is being used. The common solution I saw in RS libraries for this is to provide library specific APIs that registers a callback that is invoked in case of errors. Another common solution is to have an inverse RS that relays errors in the opposite direction. With this library specific APIs, an app running in a Servlet Container can trigger the error page algorithm depending on the error provided by the library. In this way, the error is reported upstream but using an out-of-band channel specific to each RS library. And it is *necessary* to notify the error upstream. Now we can argue forever about whether the mechanism should be part of the RS APIs or not (e.g. Subscription.cancel(Throwable)), but the decision has been made and it's not there, and can be done with an out-of-band, library-specific, callback. I'm not trying to change the RS APIs - I tried already (hello Viktor :) and been convinced that the minimalist design has advantages and that the couple of things that may be lacking can be done anyway with little effort. However, the fact that the minimalism of the RS API does not include a notify-errors-upstream mechanism does not mean that it's not necessary or not useful. I'm pretty sure that writing a WebSocket proxy would require such notify-errors-upstream mechanism, so a generic RS wrapper around the JDK WebSocket APIs would need to consider that - might be a callback or a returned Publisher in the opposite direction. I may be proven wrong - I have not written it myself and for this
Re: WebSocket
Hi Simone: Thanks for jumping in with your thoughts. On Mon, Feb 19, 2018 at 12:19 PM, Simone Bordet wrote: > Hi, > > Well, not so fast. > There are a lot of assumptions in the above code. > The first is that the ByteBuffer has a backing array, which may not be the > case. > If you write the right code that takes care of the possibility that > the ByteBuffer does not have a backing array, you end up with another > copy and more code. > More importantly, the implementation would have done all the copies > for you in order to feed your code with a final ByteBuffer. > So you are not really skipping the copies and the performance is not > different from below, where the possible copies are explicit. > Fortunately the Oracle JVM implements a backing array and the code I put out is exactly from my implementation and has been working superbly for the last year. Obviously, the day is approaching when I have to run on openJDK and I don't know if there is a backing array there since it is optional per the docs. > > DONE! More complicated, messy and very slow. (i.e. lots of wasted cpu > cycles) > > Nah :) > > ByteBufferInputStream bbis = new ByteBufferInputStream(); > for each partial ByteBuffer received by the listener { > bbis.add(byteBuffer); > } > ois = new ObjectInputStream(bbis); > MyDTO = ois.readObject(); > > Now, ByteBufferInputStream is not present in the JDK, and if you want > to complain you are in good (and conspicuous) company, as the JDK > engineers appear to avoid the issue since years now (e.g. create a > String from a ByteBuffer without copy). > Having said that, the class is trivial to implement (a naive version I > wrote is about 30 lines) and may even be provided as a utility class > by the JDK WebSocket implementers. > > The advantage is that ByteBufferInputStream can be written in a way > that performs *zero* copies, thanks to the JDK 9 WebSocket APIs - > add() would need to return a CompletableFuture. > If you don't want to confront with CompletableFutures, it can be > written in a way that performs just one copy. > Now we're talking strategy.go man!! > > To sum up: > * with JDK 9 you need a utility class that you did not need with JDK 8 > * with JDK 9 you can actually perform a zero copy provided you put a > bit of effort (or the JDK guys do) > * with JDK 9 the number of byte copies is the same or better > > All in all, anything you can do with the JDK 8 API can be done in JDK 9. > For some cases, JDK 9 is more efficient than JDK 8. > For all other cases it's on par. > JDK 9 requires a utility class to convert from ByteBuffer to InputStream. > You can do it but being the lazy creature I am I want it done for menow they're going to make me do it myself.. > > Note also that your requirement is to use blocking, stream-based, > byte[]-based APIs. > If you had chosen a data format for which a non-blocking parser based > on ByteBuffer APIs existed, you would be so happy about the JDK 9 > APIs. > Like what for instance? I'm looking for suggestions/strategies how best to adapt to the future. It's very unlikely I'm going to convert all my data to text before sending across the wire. > > I have a different experience, where clients may not be able to keep > up with the network. > This happens with browsers receiving a message and having to update a > gazillion DOM nodes (with all the ripple effects that this entails), > with clients generating so much garbage that the GC is heavily > interfering with their throughput, with proxy applications that have > different speeds on the 2 sides they proxy, and so on. > > You have my sincerest sympathy. I feel sorry for anybody who has to interface with that pathetic pile of garbage we refer to as a browser and it's even more pathetic protocol. You'd think our industry could do better. > Here I am seriously advocating to the net-dev JDK group to provide an > efficient solution, or at least start a discussion where appropriate, > for ByteBuffer to [Input|Output]Stream that is sorely missing in the > JDK. > > Thanks ! > Can we start a "Me too" movement? 😊 P. S. If you don't know about our silly American "Me too" movement consider yourself lucky! > >
Re: WebSocket
Hi, On Mon, Feb 19, 2018 at 10:55 PM, Chuck Davis wrote: >> Note also that your requirement is to use blocking, stream-based, >> byte[]-based APIs. >> If you had chosen a data format for which a non-blocking parser based >> on ByteBuffer APIs existed, you would be so happy about the JDK 9 >> APIs. > > Like what for instance? I'm looking for suggestions/strategies how best to > adapt to the future. It's very unlikely I'm going to convert all my data to > text before sending across the wire. Starting point: https://en.wikipedia.org/wiki/Comparison_of_data_serialization_formats CBOR looks promising and it's a standard. If you don't need references, then many other choices. I don't know the status of the libraries around CBOR though, so yes, I understand the appeal of Java Serialization. As I said, a JDK bridge between ByteBuffer and [Input|Output]Stream will solve a million cases. -- Simone Bordet --- Finally, no matter how good the architecture and design are, to deliver bug-free software with optimal performance and reliability, the implementation technique must be flawless. Victoria Livschitz
Re: websockets
If it's a question of resources for building a separate Flow based API on top of the existing API provided, then perhaps we could help? I could certainly implement it outside the JDK in the coming months, would the HTTP client team be willing to consider folding it in as a utility alongside the WebSocket API in the JDK? I know that's not a zero resource thing, but assuming I can produce something reasonable, reviewing it should be cheaper than implementing it. Also I don't know if there's any work being done on a TCK for this, and whether inclusion of this in the JDK would require a TCK to verify it. On 20 February 2018 at 08:41, Simone Bordet wrote: > James (hi! :) > > On Fri, Feb 16, 2018 at 12:55 AM, James Roper wrote: > > The question for me then is whether there is value in introducing an > > additional higher level API (ie, a reactive streams based API) for the > > purposes of integration with other libraries that provide RS support. > > I have mixed feeling about this. > > I first tried to push the WebSocket APIs to be Flow-based when they > were slated for JDK 9 official inclusion. > As the WebSocket APIs were moved to incubation and are now slated for > JDK 11, it may be worth considering again whether it's the case to > provide a Flow-based APIs. > > However, Pavel's point about the limits of the Flow APIs still stand, > so a Flow API may be useful, but less generic. > > Another point that makes me feeling uncertain is the good comment by > Konrad Malawski about the design of Akka Streams versus e.g. Spring's > Flowable, where the former does not implement RS or Flow interfaces, > while the latter does. > Now that we have the dichotomy of RS and JDK's Flow, it is easy for > Akka Stream implement methods such as asRSPublisher() and > asFlowPublisher() so that they work in both environments (with - yuck > - multi-release jars). > It would be harder for Spring's Flowable to provide support for both > RS and Flow. > > So at the end I would like to see a *separate* Flow API on top of the > current WebSocket API, but who's going to implement it ? > Would be great to standardize a community effort, but even better if > the JDK provided it. > > > Introducing another API, regardless of what that API is, obviously has > > drawbacks as it increases the surface area of the API, and thus > complexity, > > and also potentially introduces confusion for application developers as > they > > now have two different ways of achieving things, and they need to know > which > > to use when. So, the value of that API must be high enough to outweigh > those > > drawbacks. I strongly believe that a Reactive Streams based API does add > > enough value to do that - and the post that I shared in my previous email > > demonstrates how an ecosystem where reactive streams is embraced can > provide > > a lot of value to application developers. So I'm happy to talk more here > > about use cases and code samples etc if you don't agree here. > > I personally don't question the value of a RS or Flow API. > It's just a matter of resources - we can ask Oracle to do it, but if > they don't have resources to do it, then the road ahead is > complicated. > I see better a Flow wrapper of the JDK WebSocket APIs under the > Reactive Extension (https://github.com/Reactive-Extensions) or > Reactive Streams (https://github.com/Reactive-Streams) umbrella. > That would perhaps have less resource issues and still give a unique > library rather than a gazillion similar wrappers. > > > For signalling errors upstream, in all the cases that I've worked with, > > we've never found a reason that sending the error downstream, and just > > cancelling upstream, is a problem. At the end of the day, there is only > one > > thing that can fail, the TCP connection, and if it fails, both upstream > and > > downstream will fail - there is no such thing as a half failure in TCP. > > HttpServlet.service() allows to throw exceptions that the Servlet > container must handle by running the error page algorithm, which is > user code. > A Subscriber (provided by a library) encounters an exception while > performing its job. > Since it comes from a library, the library itself does not know how to > handle the error because it does not know in what environment it is > being used. > The common solution I saw in RS libraries for this is to provide > library specific APIs that registers a callback that is invoked in > case of errors. > Another common solution is to have an inverse RS that relays errors in > the opposite direction. > With this library specific APIs, an app running in a Servlet Container > can trigger the error page algorithm depending on the error provided > by the library. > In this way, the error is reported upstream but using an out-of-band > channel specific to each RS library. > And it is *necessary* to notify the error upstream. > > Now we can argue forever about whether the mechanism should be part of > the RS APIs or not (e.g. Subscription.cancel
Re: httpserver does not close connections when RejectedExecutionException occurs
Hi Daniel, Thank you for your comment. Dispatcher is package-private class and handle method is called at only this file in the package (sun.net.httpserver), and all call sites look like to handle exception suitably. So we can remove `throws IOException` clause without modifying the call site logic as like webrev.03. http://cr.openjdk.java.net/~ykubota/8169358/webrev.03 However, I could not find whether can I change a signature of public method without specified steps. If we need to write CSR to remove `throws IOException` clause, we should remove the clause by other issue. And I want to commit webrev.02 at this issue. http://cr.openjdk.java.net/~ykubota/8169358/webrev.02 I'd like to get your thoughts on that. P.S. I'm an author, not a committer, so I cannot access Mach5. Thanks, Yuji 2018-02-17 1:11 GMT+09:00 Daniel Fuchs : > Hi, > > On the surface I'd say that this change looks reasonable. > However, handle is declared to throw IOException, and > with this change it is guaranteed to never throw even > RuntimeException. > > It seems that the code that calls handle() - at least in > this file, has some logic to handle IOException - or > other exception possibly thrown by Dispatcher::handle, > which as far as I can see is not doing much more than what > closeConnection does. So it looks as if calling > closeConnection in handle() instead of throwing could be OK. > > However it would be good to at least try to figure out > whether there are any other call sites for Dispatcher::handle, > validate that no longer throwing will not modify the call site > logic, and possibly investigate if the 'throws IOException' clause > can be removed from Dispatcher::handle (that is: look > whether Dispatcher is exposed and/or can be subclassed and > if there are any existing subclasses). > > best regards, > > -- daniel > > > On 16/02/2018 15:29, KUBOTA Yuji wrote: >> >> Hi Chris and Yasumasa, >> >> Sorry to have remained this issue for a long time. I come back. >> >> I updated my patch for the following three reasons. >> http://cr.openjdk.java.net/~ykubota/8169358/webrev.02/ >> >> * applies to the latest jdk/jdk instead of jdk9/dev >> * adds test by modifying reproducer as like tests on >> test/jdk/com/sun/net/httpserver >> * prevents potential connection leak as Yasumasa said. For example, a >> user sets own implementation of the thread pool to HttpServer and then >> throws unexpected exceptions and errors. I think that we should save >> existing exception handler to keep compatibility and minimize the risk >> of connection leak by catching Throwable. >> >> I've tested test/jdk/com/sun/net/httpserver and passed. >> I'm not a committer, so I can not access March 5. >> >> Could you review and sponsor it? >> >> Thanks, >> Yuji >> >> 2016-11-11 12:11 GMT+09:00 KUBOTA Yuji : >>> >>> Hi Chris and Yasumasa, >>> >>> Thank you for your comments! >>> >>> I had faced connection leak on production by this handler. It seems >>> like a corner-case but it's a real risk to me. >>> I had focused REE on this issue, but it is a subclass of >>> RuntimeException, so I think that we should investigate >>> RuntimeException, too. >>> >>> If Chris agrees with the covering RuntimeException by JDK-8169358, I >>> will investigate it and update my patch. >>> If we should investigate on another issue, I want to add a test case >>> to check fixing about REE like existing jtreg, and I will create a new >>> issue after an investigation about RuntimeException. >>> >>> Any thoughts? >>> >>> Thank you! >>> Yuji >>> >>> 2016-11-11 0:56 GMT+09:00 Chris Hegarty : > On 10 Nov 2016, at 14:43, Yasumasa Suenaga wrote: > > Hi, > >> I think it best to just handle the specific case of REE, as it done in >> Yuji’s patch. > > > Will it be a cause of connection leak if RuntimeException is occurred > in handler method? No, at least not from this point in the code. > I think we should catch RuntimeException at least. Possibly, but it seems like a corner-case of a corner-case. >>> I think you can use finally statement to close the connection in this >>> case. >> >> >> I don’t believe that this is possible. The handling of the connection >> may be >> done in a separate thread, some time after execute() returns. > > > So I said we need to check the implementation of HTTP connection and > dispatcher. To me, this goes beyond the scope of the issue describe in JIRA, but if you want to investigate that, then that’s fine. -Chris. > > Yasumasa > > > On 2016/11/10 23:00, Chris Hegarty wrote: >> >> >>> On 9 Nov 2016, at 12:38, Yasumasa Suenaga wrote: >>> >>> Hi Yuji, >>> http://cr.openjdk.java.net/~ykubota/8169358/webrev.01/ >> >> >> I think Yuji’s patch is good as is. >> >>> I think you can use finally statement to close the connect
Re: WebSocket
On 19/02/2018 20:19, Simone Bordet wrote: : Now, ByteBufferInputStream is not present in the JDK, and if you want to complain you are in good (and conspicuous) company, as the JDK engineers appear to avoid the issue since years now (e.g. create a String from a ByteBuffer without copy). There is an active proposal/discussion on core-libs-dev to add a constructor to String that creates the String by decoding the bytes in a buffer. -Alan