X

Pavel Bucek's Weblog

Recent Posts

JAX-RS 2.1 Reactive Client API

I’m happy to announce that I was selected to replace Marek as JAX-RS co-spec lead. Meaning that I’ll have something to blog about during next moths, most likely until JavaOne 2017.If you are following discussions within various specifications, you might have noticed that JAX-RS was very quiet during last year. That is going to change. Or already did actually. The Expert Group (EG) is now working with updated schedule, which is mainly about following three items:Reactive Client APIServer Sent EventsNon-blocking I/OFirst two items were already proposed in some way, but were never blessed from the EG, so we need to update them (if necessary), get them reviewed and incorporate review comments. That is what happened to Reactive Client API and this post will try to summarise that change.JAX-RS Reactive Client APIFirstly, the goal of this feature is include support for reactive style programming on the client side. Not anything else. Also, we don’t want to create another client. Existing one already has support for synchronous and asynchronous request execution and we want to extend this with reactive style.Let’s see the simples example:123456CompletionStage<Response> csResponse = ClientBuilder.newClient() .target("http://oracle.com") .request() .rx() .get();You can notice couple new things, namely the returned type is not the javax.ws.rs.Response or Future<Response> (which would be the case when rx() is replaced with async()) and there is new method in Client fluent API invocation chain – rx().CompletionStage is a new interface, introduced in Java 8, which is also the only reactive standard which made it into the platform. (More about that later).rx() method has been added to be able to switch from sync/async invoker to something new – RxInvoker in this case. It defines the same methods as the others, but it doesn’t have the return type specified in the same way – you can create subclass and redefine it, for example to the CompletionStage, as it is done in CompletionStageRxInvoker, which is also part of the proposed API.There are several variants of the rx() method. One is related to providing an ExecutorService, the other one is about providing RxInvoker class. The former is simple to explain – reactive invocations are async by nature and we want to be able to specify the thread pool / executor service, which will be used to invoke that (which might be revisited later, for example removed by allowing client-wide async executor service configuration), the latter is about extensibility. That deserves another section, so..:Reactive ExtensionsIf you are implementing reactive application on Java, you most likely know other datatypes, provided by various frameworks. Namely Guava, RxJava and others. They do provide similar functionalities to CompletionStage, but with different APIs. Those can be beneficial to use, especially if you have an application already written using other, non-standard, frameworks and JAX-RS wants to make itself usable as easily as possible. Let’s start with code example:12345678Client client = ClientBuilder.newClient();client.register(FlowableProvider.class); Flowable<Response> csResponse = client.target("http://oracle.com") .request() .rx(FlowableInvoker.class) .get();Here, we do see how RxJava2 Flowable could be used when getting a JAX-RS Response.Both FlowableProvider and FlowableInvoker are provided by the 3rd party – for example, if RxJava2 developer community things JAX-RS in important enough, they might release extension module, which will contain these classes. Also, as always, any JAX-RS implementation can choose the features and might provide similar provider as part of their implementation.I don’t want to get into more detail, since this might be changed, but for now it seems like we have reached a conclusion, that this is the best possible way how the extensibility can be provided. If you are interested in knowing the decision process, feel free to read JAX-RS spec EG mailing list.I hope you like newly proposed API. If you have any comments, please share them at the users mailing list on JAX-RS project!Links, mailing lists, etc.JAX-RS JCP page: https://jcp.org/en/jsr/detail?id=370JAX-RS EG mailing list archive: https://java.net/projects/jax-rs-spec/lists/jsr370-experts/archive JAX-RS users mailing list: users@jax-rs-spec.java.netJAX-RS source repository (Github mirror): https://github.com/jax-rs/api

I’m happy to announce that I was selected to replace Marek as JAX-RS co-spec lead. Meaning that I’ll have something to blog about during next moths, most likely until JavaOne 2017. If you are following...

WebSocket Client API – Java 8

Since Java 8 was released, lots of new or reworked APIs emerged, simply because Java 8 is really evolutionary step in Java language specification and it is definitely worth to update the APIs to enable newly added features.Unfortunately, Java EE APIs have different release cycle and we’d need to wait a little bit for next version, but I was able to add at least something to Tyrus, which is reference implementation of JSR 356 – WebSocket API for Java. There are some other changes which could be made, but most of them require changes in the API itself, which we cannot do at the moment, so I focused on other features which do enhance the experience. You can view this as the “first” attempt to bring some Java 8 API features into the existing programming model.The area covered in this post is Client API – mainly because this change can be used easily with any WebSocket API implementation; it is built on top of existing API. If I would be thorough, I’d apply this to deployment of the programmatic endpoints on the server side as well, but that would be far more work and since the server side usually uses annotated endpoints instead of programmatic ones, I believe this should be sufficient to evaluate the proposal and provide any feedback you might have.The client API was originally crafted as something, which should be similar to the JavaScript counterpart, but the language differences at that time diminished that effort to basically just naming and few other details (and the alignment with server side API had higher priority). Anyway, I believe it is the time, when we should reconsider Client API (and programmatic model in general).If you look at javascript API, it’s basically just one object, to which you can set handlers for some events:123456window.websocket = new WebSocket(window.wsUrl("/sample-btc-xchange/market")); var websocket = window.websocket; websocket.onopen = function () { /* ... */ }; websocket.onmessage = function (evt) {/* ... */ }; websocket.onclose = function () { /* ... */ }; websocket.onerror = function () { * ... */ };The current Java version of this would be:123456789101112131415161718client.connectToServer(new Endpoint() { @Override public void onOpen(Session session, EndpointConfig EndpointConfig) { try { session.addMessageHandler(new MessageHandler.Whole() { @Override public void onMessage(String message) { }); } } } @Override public void onClose(Session session, CloseReason closeReason) { } }, ClientEndpointConfig.Builder.create().build(), getURI(EchoEndpoint.class));which does not seem nice to me, additionally, since Lambdas and Method References were added to the language, we could do much better than that. The main idea behind these changes is that programmatic endpoint (class javax.websocket.Endpoint) is no longer necessary, since it can be replaced by three method references, especially when you usually don’t need all of them. And Java 8 offers nice predefined Functional Interfaces, which work just fine, so we don’t even need to introduce declaration of those, we only need to define consumed types.With these in mind, the previous code could look like:1234Session session = new SessionBuilder().uri(getURI(SessionBuilderTestEndpoint.class)) .messageHandler(String.class, message -> { }) .onClose((session, closeReason) -> { }) .connect();The main advantage I see here (other than readability) is that the configuration is no longer in two places – programmatic connectToServer method requires Endpoint, ClientEndpointConfig and other parameters, but it does not allow to register MessageHandler right away – user needs to implement that logic in @OnOpen method. On the other hand, proposed approach does that for you, so @OnOpen implementation in this case will be only what it is supposed to be. And I believe it could be omitted in lots of cases, which also contributes to readability and ease of use. Also, last but not least, less code written, less bugs introduced..Previous code sample included lambdas, but sometimes, you might want to have more complicated code there, which does not look good implemented as lambda. In that case, you can declare standard methods with appropriate parameters and provide Method Reference instead. Slightly more complex sample would then look like:123456Session s = new SessionBuilder().uri(getURI(SessionBuilderTestEndpoint.class)) .onOpen(this::onOpen) .messageHandler(String.class, this::onMessage) .onError(this::onError) .onClose(this::onClose) .connect();More code examples can be seen in SessionBuilderTest class.You are welcomed to try and give us your feedback. The SessionBuilder is in module “org.glassfish.tyrus.ext:tyrus-client-java8″, which is currently released only as snapshot (should be part of next Tyrus release), so you’ll need to add reference to maven.java.net snapshot repository: https://maven.java.net/content/repositories/snapshots/Complete dependencies and repo declaration in pom.xml might look like:1234567891011121314151617 org.glassfish.tyrus.ext tyrus-client-java8 1.11-SNAPSHOT org.glassfish.tyrus tyrus-container-grizzly-client 1.11-SNAPSHOT maven.java.net-snapshots https://maven.java.net/content/repositories/snapshots/Any feedback appreciated!Linkshttps://tyrus.java.net/mailing listhttps://java.net/jira/browse/TYRUS

Since Java 8 was released, lots of new or reworked APIs emerged, simply because Java 8 is really evolutionary step in Java language specification and it is definitely worth to update the APIs...

WebSocket vs REST

As controversial or potentially “flame starting” topic this might seem to be, don’t worry. I will approach this purely from pro-WebSocket view and the comparison with REST will be done on the sample, which heavily favours WebSocket ;) Not that long ago, I had to explain one of my colleague where he should consider using WebSocket protocol and I realised, that lots of people don’t really know about it much. I even heard question whether WebSocket is successor of REST, like REST was/is to SOAP web services.. well, I’ll try to make this little bit clearer in this post. For starters, WebSocket is NOT REST replacement. These are two technologies, which can coexist very nicely even in single application or webpage. Both are doing similar things and for some applications are even interchangeable. Bold statement, but it’s true. Both approaches have it’s own pros and cons, as with everything else.. Let’s go little back to the history of web services and remember why was WebSocket protocol even created – to allow bi-directional communication with clients, mainly represented by web pages. It was (and still is) possible to achieve the same with plain REST, but there are some issues with it. Let’s name two of them: REST is always Request/Response “stateless” communication, by the nature of the HTTP protocol, lots of information must be sent in each Request and response. The first one implies simple fact – web server cannot send anything to the webpage without a Request. There are various workarounds (yes, workarounds. First real standard solution is WebSocket protocol) like long polling or JSONP, but they are solving only the communication from server to client, which implies that there needs to be the other channel from client to server. And we are getting to the second item in short list above – efficiency. When the application needs to communicate frequently with the server, the volume of HTTP traffic can be really big. Now try to compute the entropy (how much information is acquired due to observation of the Request/Response) and see how much redundant and unimportant bytes is sent with each HTTP communication. This is already addressed in HTTP/2, but anyway, the overhead still exists. I intentionally skip the HTTP/2 server push implementation – I plan to address that in another blogpost. Enough with history lesson and plain “code-less” chatter. You might remember Shared collection sample introduced couple of moths ago in Tyrus workspace – the last modification of it was inspired by the discussion with that colleague – I wanted to compare REST and WebSocket implementation of the same thing. Quick recapitulation – the sample exposes a map-like object in JavaScript and Java and synchronises their changes using WebSocket. Additionally you can register listeners on both sides, so you always know when anyone changes anything.. basically very simple and fragile implementation of coherence/hazelcast/yourFavouriteDistributedFramework. As you most likely already expect, I implemented the same thing (or extended that implementation) to support REST based transport instead of WebSocket. I must admit I cheated a little – I used Server-Sent Events (SSE), which is not really RESTful, but this feature is implemented as part of Jersey, which is Reference Implementation of JAX-RS: The JavaTM API for RESTful Web Services and also my favourite REST framework (I used to be a contributor, so consider this as another very-impartial fact). SSE also has simple JavaScript API implemented in all modern browsers, so it was an easy decision for me – I have the channel from server to client covered and the other way will be just standard request using XMLHttpRequest (or an ActiveXObject when in M$ Internet Explorer). Below is the simple scheme with mentioned protocols. When you compile and deploy the sample, the standard behaviour is actually quite comparable (I’m on localhost, so that is not that much surprising), both maps receive and send updates and the experience is almost the same. So let’s look under the hood… When you create or modify a map entry, browsers sends and event. In case of WebSocket, it is short (text) message containing Json “object” + few bytes (let’s say 8) of overhead – WebSocket message “header”. On the other hand, when you do the same action on REST version of the page, HTTP Request is sent (and Response received – it does not contain anything, just status, headers and no entity): I don’t even want to know what is the overhead in this case… You might say that it does not matter, since we are not connected using 33.6 kbps modems.. well, that’s true, but every byte introduces some delay, additional handling in the network and even app servers – they have to read/write that byte, even when it won’t be used. And that’s not everything related to the resources utilisation – imagine, that every such Request created new TCP connection to the server (which does not need to be true when HTTP keep-alive is used). Since I’m still on localhost, I wanted to push the bar little higher and wrote simple performance test: method, which will create 10k updates of single map entry (you can execute it by clicking on [PerfTest] button on the sample page – both Rest and WebSocket version have it). Starting with WebSocket – it does what is expected and I can measure how long it takes to have some comparison with REST.. but.. the problem is that the REST version does not even finish. I did not dig into that that much, but seems like every browser has some kind of limit for JavaScript requests. I was usually able to achieve something around 3-5k Requests, but after that, browser “run out of resources”, most likely to protect itself or the target site from potentially DDoS-y case. Conclusion? If you need truly bi-directional communication, with high frequency of shorter messages (it is far easier to handle those in JavaScript than big ones), you should consider using WebSocket. On the other side, if you have some application, which already works well and uses REST efficiently, you don’t need to change that! REST is still the best solution for lots of use cases, you should look at these two technologies/protocols as complements, not as competitors. And please don’t forget, that this was not by any means an attempt for unbiased comparison :-) Any comments/feedback is appreciated! Links Tyrus: https://tyrus.java.net Complete example on Github

As controversial or potentially “flame starting” topic this might seem to be, don’t worry. I will approach this purely from pro-WebSocket view and the comparison with REST will be done on the sample,...

Why Checkstyle matters...

I’ve read something about ZeroMQ and its java clone recently and decided I should give it a try. JeroMQ is quite small project (same as ZeroMQ I guess), so I decided to checkout the sources directly, since that usually gives me last version of everything, including samples etc. When I opened the project in my IDE, I noticed some minor issues in the code, starting with some unnecessary properties, ending with missing null checks and invalid String comparisons. (You can find these in any project, so that was not so surprising).Interesting part started when I fixed the issues locally and ran “mvn clean install” to verify my changes, build failed. No surprises there ;) but it failed on check style issues. That was something I did not expect. It turned out, that the project enforces defined set of rules. Not saying that I like the style chosen for that particular project (common guys, its Java, not C), I really liked the idea behind that decision.Generally, it is far better when single project uses single code style – developer might need to adapt to that and it can take time, but for me, when I got past this period, code is much easier to read and understand, because I don’t need to think about that particular formatting, looking for potentially mistyped code blocks or parenthesis etc. Even when switching among projects with different code style, it is still better than having to adapt to various styles in single module or even class. (Yes, that happens. In any older project, which accepted contributions from lot of people).After this reflection, I thought about applying this to one project, where I can do almost anything I want – Tyrus. Short version: I did it!Slightly longer version: It was a pain. Really. And I don’t have by any chance that rich check style rule set as mentioned JeroMQ. To be honest, I thought that we should be fine, since we do often detailed code reviews, but you can always miss something which is not really well formatted.. Nice fact about Checkstyle is, that there are no compromises. You can exclude some rules for some class or even some lines of that class, but .. why? It would add unnecessary housekeeping when modifying the code and it could be accidentally disabled by just refactoring the class name. So I went for “zero tolerance” for defined rules.The problem is, that there is no simple tool which would fix all check style issues. It kind of makes sense, since lots of them are not easily fixable automatically. Anyway, I found some recipe which involved Eclipse plugin and generating Eclipse formatter from checkstyle.xml. That worked somehow and the formatter can be exported and included to other IDEs (I personally use IntelliJ). There are some issues. One of caveats was max line length. The formatter was able to “clean” these warnings from the build, but sometimes produced code like:12345678910if (wseMaxSessionsAnnotation != null) { TyrusServerEndpointConfig.Builder builder = TyrusServerEndpointConfig.Builder.create(annotatedClass, wseAnnotation .value()). encoders( encoderClasses) .decoders(decoderClasses) .subprotocols( Arrays.asList( subProtocols));Which is far from acceptable :). Long story short, I ended up with defining own formatting rules, setting them in IntelliJ code style, reformatted and then manually checked and fixed issues in all changed source files. It was originally ~500 files, it shrunk a little after my review, since I removed all non-java files from that change. You can see the commit at github (don’t worry if it takes some time to load, it is a bigger one).Anyway, I’m still glad I did that. Now I know that once the build or pull request passes, it has the code already formatted in a way, that I don’t need to check it (that much). If you are interested, there is checkstyle-build.xml used for build time validation, and the configuration in pom.xml.What can be better? IntelliJ and I guess even other IDEs could be more accessible for checkstyle configuration. Meaning that formatter/code style/… should have better support for importing checkstyle config file + it should be able to actually use it well. The latter statement is almost true (for some edgecases, which cannot be easily solved I guess), so the first one is more important. Since I know that the settings are already there and its only about correct values of some properties, I cannot see it is not already there.That’s it for now ;) Hopefully you’ll feel inspired and try to at least run the checkstyle configured to your code style and see whether you can incorporate it easily in your build. If you have any suggestions or comments about this topic, please share them with me, especially if I left out something usable for Tyrus or other projects. Thanks!

I’ve read something about ZeroMQ and its java clone recently and decided I should give it a try. JeroMQ is quite small project (same as ZeroMQ I guess), so I decided to checkout the sources directly,...

Tyrus 1.10

Tyrus 1.10 is a maintenance relase, so unfortunately no cool new features to highlight, but we were able to add some new examples – Shared collection and BTC Xchange.Complete list of fixed issues is below. I would like to thank to java.net users “toto2″ and “gray” for their help with GLASSFISH-21213. There is one other issue worth mentioning and that is TYRUS-329. In 1.10 release, Tyrus (after added tests for Per-Message compression) becomes fully compliant with Autobahn Test Suite.Let me shortly introduce the new samples which were added in this version, just to make this blog post justifiable :).Shared Collection SampleIn this example I tried to explore one possibility of data sharing between JavaScript client and Java code. The sample name could be misleading, the only implemented collection is a Map, which is backed up by WebSocket connection going back to the server. Both sides do implement “standard” Map, with some added flavour of distributed structures – update listener.If you want to try it, you can follow the instructions in README.html; the application should present itself with a simple JavaScript based interface to modifying the content of the map. Don’t modify the content right away, open it in another window and observe how fast are changes propagated to other window(s).BTC Xchange SampleAnother sample which demonstrates simple-to-implement communication with JavaScript code. On the title page you can see the graph, which in this case represents current exchange rate BTC/USD and there are some buy and sell proposals which can be executed. The sample currently allow you to go to “red numbers”, but you can create few simple modifications and make a “game” from that – the sample can be also opened from multiple windows and you can try to compete with someone else; for example, you can make a goal of getting some amount of USD or BTC :)Complete list of changes[TYRUS-394]  – Proxy bypassed on Linux but not on Windows.[TYRUS-391]  – Tyrus reconnect handler not reached on Android.[TYRUS-393] – Incorrect handling of sending whole message during (unfinished) partial message.[TYRUS-329] – Deflate extension fixes – autobahn test suite.[GLASSFISH-21213] – Deadlock (HttpSession vs TyrusWebSocket).

Tyrus 1.10 is a maintenance relase, so unfortunately no cool new features to highlight, but we were able to add some new examples – Shared collection and BTC Xchange. Complete list of fixed issues is...

Is WebSocket Session really thread safe?

Todays article would be about one simple use-case of JSR-356: Java API for WebSocket. This was brought to my attention by Mark Thomas, who started relatively long thread on the jsr356-experts mailing list. The described problem can be simplified to following code:12session.getAsyncRemote().sendText(message);session.getBasicRemote().sendText(message);You might be wondering what is the problem here.. first message is sent asynchronously and the second one synchronously. Session object itself is meant to be thread safe (last paragraph on class level javadoc), but there is a problem with container itself, more precisely with RemoteEndpoint.Basic interface, see following quote of its documentation:If the websocket connection underlying this RemoteEndpoint is busy sending a message when a call is made to send another one, for example if two threads attempt to call a send method concurrently, or if a developer attempts to send a new message while in the middle of sending an existing one, the send method called while the connection is already busy may throw an IllegalStateException.What I get from this paragraph is that the second line (from the sample above) can throw an IllegalStateException, when previous message is not sent. To be honest, reference implementation did not throw that exception (ever) and I don’t believe that any sample application or any WebSocket application I wrote checks for that state. Anyway, the javadoc does not mention that it MUST throw an exception, so for the mentioned sample, it is ok to block the second send until both messages are sent.Unfortunately, that’s not all :). WebSocket API also allows sending partial messages and when you mix partial messages and whole messages in this context, you might start getting small headache… let’s consider following:123session.getBasicRemote().sendText(message, false); // partial msgsession.getBasicRemote().sendBinary(data);session.getBasicRemote().sendText(message, true); // partial msgIn this sample, the second message should not be sent before the message from third line. Problem arises when this sequence is executed from a single thread – if second line blocks until text message is completed, we would have a problem. Implementation cannot really assume what will or won’t happen and generally it does not want to block the thread for a long time, so throwing IllegalStateException seem to be relatively OK.(Sidenote: reference implementation, Tyrus, did not handle this scenario correctly.  The issue related to this functionality was filed as TYRUS-393 and the fix will be present in next released version – 1.10)Since this seem to be grey area in the specification (it says what “may” be done, not what MUST or MUST NOT be done), the implementation can choose whatever it want – actually I believe that blocking the thread and waiting until it can send a message is valid, specification compliant approach. For Tyrus, I implemented little more defensive solution: the implementation waits (blocks the thread) for short period of time and if the conditions still don’t allow sending the message, IllegalStateException will be thrown.Conclusion is not as clear as it should be – WebSocket Session object is thread safe for sure, but there are some conditions and states, which might be surprising and confusing for common users of this API. All of them can be prevented by following some rules when using WebSocket Sessions – for example if you are sending only whole messages synchronously, you don’t need to care about anything. If you are sending messages only asynchronously, it should be similar, but you might encounter some discrepancies among the implementations. When you want or need to send partial message, the issue might be harder to deal with – since WebSocket Session does not offer any way how to check the current state, it will need to be stored somewhere else and checked before invoking send* methods. My current advice is that the applications you write should add handling of  IllegalStateException from RemoteEndpoint.Basic.send* methods, especially if you expect that it can be run on different JSR 356 implementation.

Todays article would be about one simple use-case of JSR-356: Java API for WebSocket. This was brought to my attention by Mark Thomas, who started relatively long thread on the jsr356-experts mailing...

Reducing WebSocket client jar size with ProGuard

We already know there is a demand for standalone web socket client runnable even on different platforms than just Java EE or Java SE – Tyrus publishes client runtime all-in-one bundles for Java 6 (works on Android!) and Java 7+ (takes advantage of NIO API introduced in Java 7). In following article, we will try to create optimised version of these bundles to see whether they do contain some redundant classes. (spoiler: they do). Tool of the choice for todays exercise would be ProGuard. Maybe not that easy to use, but it is low-level tool capable of various optimisations. We won’t cover any obfuscation, our goal is to create smaller jar with the same functionality. Starting point is: 551K tyrus-standalone-client-jdk-1.10-SNAPSHOT.jar1.9M tyrus-standalone-client-1.10-SNAPSHOT.jar These jar files are representing two distribution which were already mentioned – client-jdk is Java 7 based client, client jar is Grizzly based (JDK 6+). For those who don’t know, Grizzly is Java NIO container, so it basically does the same thing as Java 7 NIO API, but in a little different manner. Also, Grizzly is the NIO framework of choice for Glassfish, Java EE reference implementation. Downloading and executing ProGuard is not complicated, there is even GUI if you are more used to this kind of applications. After initial study and few trial runs, it seems I can produce optimised jar files with following configuration: tyrus-client.pro 1 2 3 4 5 6 7 8 9 10 11 12 13 14 -dontoptimize -dontobfuscate -keepparameternames -keepattributes Signature,InnerClasses,*Annotation* -keepclassmembers,allowoptimization enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keep public class org.glassfish.tyrus.** { public protected private *; } -keep public class javax.websocket.** { public protected *; } -dontwarn  The command line for running this configuration against Tyrus client distributions would look somehow like following: 1 proguard.sh -injars ./client-jdk/target/tyrus-standalone-client-jdk-1.10-SNAPSHOT.jar -outjars tyrus-client-jdk.jar -libraryjars $JAVA_HOME/jre/lib/rt.jar @tyrus-client.pro (previous line is for client-idk distribution, but it is very similar to the other one; just for the completeness of presented data, I’m using JDK 8; if you are using different version, your “-libraryjars” parameter might need to be adjusted). Result: 533K tyrus-client-jdk.jar1.2M tyrus-client.jar For the Java 7+ client distribution, the difference is actually quite small, so we can make an assumption that the distribution is already quite optimal. The other is different story – but there is a good reason for it. Java 6+ distribution is based on Grizzly and Grizzly is mainly written as a server, not as a client. We are reusing some stuff from there, but the problem seem to be in not optimal modularization for client usecases. Anyway, just to sum that up, ProGuard was able to find and remove approximately 700 kB of “not used code”. The conclusion is that you should consider using tool similar to ProGuard, especially when you are redistributing any java application. Special note for Android developers: you are already doing this, maybe even without knowing – DexGuard seem to be standard part of Android application development lifecycle.

We already know there is a demand for standalone web socket client runnable even on different platforms than just Java EE or Java SE – Tyruspublishes client runtime all-in-one bundles for Java 6...

New Tyrus sample - Shared Collection

Sometime in JavaOne 2014 timeframe colleague came to me and showed me Meteor.js library, which seems to be really nice javascript framework, client and server side (kudos to the authors!). I started looking at the docs and examples and discovered leaderboard sample. In short, it is about having javascript collection backed up by some (persistent) storage on the server side, which is also shared (or replicated, if you wish) to all other clients. Meteor.js does this in Javascript “class” called Mongo.Collection (used to be Meteor.Collection, but it was renamed before 1.0 release). I really liked the idea and dug little bit more into the implementation and saw that they are using Socket.IO for the communication with the server, which is basically websocket (+fallback and other handy features). Long story short – I wanted to do something similar and ideally publish it as Tyrus sample :-) and it wasn’t that hard! Obviously, this task is more about client javascript implementation than about what is going to happen on the server side, but it was refreshing experience – next step is Tyrus version of  Socket.IO (nah, I’m kidding…). I don’t really want to go into details in javascript implementation, since I don’t feel very confident about that (and you can check it out in the Tyrus sources), but the goal was to create a java map-like API to store data and have it synchronized using WebSocket with all other client. 1 2 3 4 5 6 7 8 9 10 /** * Create new Tyrus map. * * @param {string} url * @param {function} updateListener * @constructor */ Tyrus.Collection.Map = function (url, updateListener) { // … } I created Tyrus.Collection namespace and “class” Map in it. The constructor have two arguments – URL of websocket endpoint and update listener. Update listener is invoked whenever the map is changed (this is not optimal, so currently it might be called even when you are putting the key value pair which is already there). Map has following public methods, which should feel familiar for java developers: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 /** * Get size of the map. * * @returns {Number} number of records in the map. */ self.size = function () { }; /** * Return {@code true} when the map is empty. * * @returns {boolean} {@code true} when the map is empty, {@code false} otherwise. */ self.isEmpty = function () { }; /** * Get value corresponding to provided key from a map. * * @param {string} key key. * @returns {*} value for corresponding key or {@code null} when there is no such key. */ self.get = function (key) { }; /** * Put an item into the map. * * @param {string} key key. * @param {*} value value. */ self.put = function (key, value) { }; /** * Remove key (and corresponding value) from the map. * * @param {string} key key to be removed. */ self.remove = function (key) { }; /** * Clear the map. */ self.clear = function () { }; /** * Get the key set. * * @returns {Array} array containing all keys from the map (as indexes AND values - TODO). */ self.keySet = function () { }; Server side implementation was quite simple and it currently stores the info only in static map. You can easily extend this by persisting the map to file/database/anywhere else. The communication is driven by very simple protocol, which broadcasts mutating messages to other clients. All get operations are handled by client-side javascript, the map on the server side is kept in sync only because it is a source for clients connected later – this is why this is just “shared” map, not “distributed” (which would be more complicated to implement). The source of the sever endpoint can be found on github, in samples directory: SharedCollectionEndpoint. Instruction how to run this sample are included in README.html in sample root dir. When you access the front page, you should see something like: You can add/modify existing items in the map by using the form on the bottom side (it will automatically load an item when you click on it) and you can remove any item by clicking on the red cross on the right side. All changes should be automatically propagated to all other clients (just open the page in another browser window). Hope you’ll enjoy the new sample and if you have any comments or suggestions, please send us a note to users@tyrus.java.net. Links Tyrus: https://tyrus.java.net Shared Collection Sample sources: (github) Shared Collection Sample war: (maven.java.net)

Sometime in JavaOne 2014 timeframe colleague came to me and showed me Meteor.jslibrary, which seems to be really nice javascript framework, client and server side (kudos to the authors!). I started...

Tyrus 1.9

Long time no see! After a while (longer than anticipated, sorry about that), we cut off Tyrus 1.9 release. Not much changed in the code since last release, but we were able to squeeze in some stability updates and performance improvements. I’ll highlight some of the features or fixes in next paragraphs:What’s new?Petr worked on new feature tracked as TYRUS-289 – Debug mode. Now you can enable more verbose logging on server, which would start logging data like handshake request and response, application and endpoint configuration and information about sessions and even messages, if you want. This could be useful for answering questions like “Why I cannot access my websocket endpoint?!” and so on.Ondřej spent some time playing with debugger and found out few code paths, which were improved. Namely instantiating default (stateless) encoders and decoders per endpoint, which will save some memory and unnecessary calls to message localization code.Another topic worth mentioning is that we fixed (again) client runtime on Android, so if you are looking (or already using) Tyrus client on Dalvik/Art, you should be able to update to 1.9.Complete list of resolved JIRA tickets is below. As always, if you have any feedback, please use our mailing list users@tyrus.java.net or create a new bug or enhancement request  at https://java.net/jira/browse/TYRUS/. You can also use stackoverflow – in that case, please use tag “tyrus“.Complete list of changes[TYRUS-285] – Improve broadcast by sending from multiple (configurable) threads.[TYRUS-289] – DEBUG mode (client/server)[TYRUS-307] – Revise ignored tests[TYRUS-342] – Tyrus throw CancellationException[TYRUS-355] – HTTP Redirect – Location header cannot be a relative address[TYRUS-361] – JVM does not exits if shared transport is enabled[TYRUS-365] – Broadcast messages are not included in the monitoring statistics[TYRUS-366] – master branch not buildable with JDK 1.6[TYRUS-368] – Instantiate default encoders and decoders once per endpoint[TYRUS-369] – Format localized messages when necessary[TYRUS-370] – Masking key is generated on server side[TYRUS-371]– Introduce an option for using custom masking key generator.[TYRUS-375] – Buffer overflow during HTTP Response size parsing (jdk client container)[TYRUS-376] – Investigate how/whether is ScheduledExecutorService terminated when session is closed (related to heart beat feature)[TYRUS-379] – Autobahn testcases 7.3.4 & 7.3.5 fail in close stage[TYRUS-380] – setContextClassLoader throws “access denied” exception in JNLP client app[TYRUS-381] – exception message error[TYRUS-382] – onError parameter exception is wrapped in InvocationTargetException when an exception is thrown from programmatic endpoint (onOpen or onClose)[TYRUS-383] – session.getRequestParameterMap does not contain query parameters when running on Grizzly standalone server[TYRUS-385] – Session idle timeout concurrency issues[TYRUS-386] – Dalvik class loader rejects TyrusEnpointWrapper[TYRUS-387] – Unable to use Tyrus in android appllication

Long time no see! After a while (longer than anticipated, sorry about that), we cut off Tyrus1.9 release. Not much changed in the code since last release, but we were able to squeeze in some stability...

Tyrus 1.8

Another version of Tyrus, the reference implementation of JSR 356 – Java API for WebSocket is out! Complete list of fixes and features is below, but let me describe some of the new features in more detail. All information presented here is also available in Tyrus documentation. What’s new? First to mention is that JSR 356 Maintenance review Ballot is over and the change proposed for 1.1 release was accepted. More details about changes in the API can be found in this article. Important part is that Tyrus 1.8 implements this API, meaning you can use Lambda expressions and some features of Nashorn without the need for any workarounds. Almost all other features are related to client side support, which was significantly improved in this release. Firstly – I have to admit, that Tyrus client contained security issue – SSL Hostname verification was not performed when connecting to “wss” endpoints. This was fixed as part of TYRUS-339 and resulted in some changes in the client configuration API. Now you can control whether HostnameVerification should be performed (SslEngineConfigurator#setHostnameVerificationEnabled(boolean)) or even set your own HostnameVerifier (please use carefully): #setHostnameVerifier(…). Detailed description can be found in Host verification chapter. Another related enhancement is support for Http Basic and Digest authentication schemes. Tyrus client now enables users to provide credentials and underlying implementation will take care of everything else. Our implementation is strictly non pre-emptive, so the login information is sent always as a response to 401 Http Status Code. If the Basic and Digest are not good enough and there is a need to use some custom scheme or something which is not yet supported in Tyrus, custom Authenticator can be registered and the authentication part of the handshake process will be handled by it. Please seeClient HTTP Authentication chapter in the user guide for more details. There are other features, like fine-grain threadpool configuration for JDK client container, build-in Http redirect support and some reshuffling related to unifying the location of client configuration classes and properties definition – every property should be now part of ClientProperties class. All new features are described in the user guide – in chapterTyrus proprietary configuration. Update – Tyrus 1.8.1 There was another slightly late reported issue related to running in environments with SecurityManager enabled, so this version fixes that. Another noteworthy fixes are TYRUS-355 and TYRUS-361; the first one is about incorrect thread factory used for shared container timeout, which resulted in JVM waiting for that thread and not exiting as it should. The other issue enables relative URIs in Location header when using redirect feature. Links Tyrus homepage mailing list JIRA Complete list of changes: Bug [TYRUS-333] – Multiple endpoints on one client [TYRUS-334] – When connection is closed by a peer, periodic heartbeat pong is not stopped [TYRUS-336] – ReaderBuffer.getNextChars() keeps blocking a server thread after client has closed the session [TYRUS-338] – JDK client SSL filter needs better synchronization during handshake phase [TYRUS-339] – SSL hostname verification is missing [TYRUS-340] – Test PathParamTest are not stable with JDK client [TYRUS-341] – A control frame inside a stream of continuation frames is treated as the part of the stream [TYRUS-343] – ControlFrameInDataStreamTest does not pass on GF [TYRUS-345] – NPE is thrown, when shared container timeout property in JDK client is not set [TYRUS-346] – IllegalStateException is thrown, when using proxy in JDK client [TYRUS-347] – Introduce better synchronization in JDK client thread pool [TYRUS-348] – When a client and server close connection simultaneously, JDK client throws NPE [TYRUS-356] – Tyrus cannot determine the connection port for a wss URL [TYRUS-357] – Exception thrown in MessageHandler#OnMessage is not caught in @OnError method [TYRUS-359] – Client based on Java 7 Asynchronous IO makes application unexitable Improvement [TYRUS-328] – JDK 1.7 AIO Client container – threads – (setting threadpool, limits, …) [TYRUS-332] – Consolidate shared client properties into one file. [TYRUS-337] – Create an SSL version of Basic Servlet test New Feature [TYRUS-228] – Add client support for HTTP Basic/Digest Task [TYRUS-330] – create/run tests/servlet/basic via wss [TYRUS-335] – [clustering] – introduce RemoteSession and expose them via separate method (not include remote sessions in the getOpenSessions()) [TYRUS-344] – Introduce Client support for HTTP Redirect

Another version of Tyrus, the reference implementation of JSR 356 – Java API for WebSocket is out! Complete list of fixes and features is below, but let me describe some of the new features in more...

WebSocket API 1.1 released!

Its my please to announce that JSR 356 – Java API for WebSocket maintenance release ballot vote finished with majority of “yes” votes (actually, only one eligible voter did not vote, all other votes were “yeses”). New release is maintenance release and it addresses only one issue:  WEBSOCKET_SPEC-226.What changed in the 1.1?Version 1.1 is fully backwards compatible with version 1.0, there are only two methods added to javax.websocket.Session:1234567891011121314151617181920212223242526272829303132/*** Register to handle to incoming messages in this conversation. A maximum of one message handler per* native websocket message type (text, binary, pong) may be added to each Session. I.e. a maximum* of one message handler to handle incoming text messages a maximum of one message handler for* handling incoming binary messages, and a maximum of one for handling incoming pong* messages. For further details of which message handlers handle which of the native websocket* message types please see {@link MessageHandler.Whole} and {@link MessageHandler.Partial}.* Adding more than one of any one type will result in a runtime exception.** @param clazz   type of the message processed by message handler to be registered.* @param handler whole message handler to be added.* @throws IllegalStateException if there is already a MessageHandler registered for the same native*                               websocket message type as this handler.*/public void addMessageHandler(Class<T> clazz, MessageHandler.Whole<T> handler); /*** Register to handle to incoming messages in this conversation. A maximum of one message handler per* native websocket message type (text, binary, pong) may be added to each Session. I.e. a maximum* of one message handler to handle incoming text messages a maximum of one message handler for* handling incoming binary messages, and a maximum of one for handling incoming pong* messages. For further details of which message handlers handle which of the native websocket* message types please see {@link MessageHandler.Whole} and {@link MessageHandler.Partial}.* Adding more than one of any one type will result in a runtime exception.*** @param clazz   type of the message processed by message handler to be registered.* @param handler partial message handler to be added.* @throws IllegalStateException if there is already a MessageHandler registered for the same native*                               websocket message type as this handler.*/public void addMessageHandler(Class<T> clazz, MessageHandler.Partial<T> handler);Why do we need to add those methods? Short and not precise version: to support Lambda expressions as MessageHandlers.Longer and slightly more precise explanation: old Session#addMessageHandler method (which is still there and works as it worked till now) does rely on getting the generic parameter during the runtime, which is not (always) possible. The unfortunate part is that it works for some common cases and the expert group did not catch this issue before 1.0 release because of that. The issue is really clearly visible when Lambdas are used as message handlers:123session.addMessageHandler(message -> { System.out.println("### Received: " + message);});There is no way for the JSR 356 implementation to get the type of the used Lambda expression, thus this call will always result in an exception. Since all modern IDEs do recommend to use Lambda expressions when possible and MessageHandler interfaces are single method interfaces, it basically just scream “use Lambdas” all over the place but when you do that, the application will fail during runtime.Only solution we currently have is to explicitly provide the type of registered MessageHandler. (There might be another sometime in the future when generic type reification is introduced, but that is not going to happen soon enough). So the example above will then be:123session.addMessageHandler(String.class, message -> { System.out.println("### Received: " + message);});and voila, it works.There are some limitations – you cannot do1List<String>.class, so you will need to encapsulate these types when you want to use them in MessageHandler implementation (something like “class MyType extends ArrayList<String>”). There is no better way how to solve this issue, because Java currently does not provide good way how to describe generic types.The api itself is available on maven central, look for javax.websocket:javax.websocket-api:1.1. The reference implementation is project Tyrus, which implements WebSocket API 1.1 from version 1.8.

Its my please to announce that JSR 356 – Java API for WebSocket maintenance release ballot vote finished with majority of “yes” votes (actually, only one eligible voter did not vote, all other votes...

Tyrus 1.7

This release cycle was shorter comparing to previous ones and the main purpose was to integrate and align with upper stack projects. Despite that fact there are some new features and bugfixes:What’s new?Ondřej added nice feature which allows to limit opened WebSocket sessions. And it is configurable, currently supported scopes of limitations are “per endpoint”, “per client remote address” and “per application”. This should allow effective control of server-side resources. For now, the values are static and constant, but if there will be a demand for creating more advanced session limit support, like dynamic load-balancing among set of endpoints etc, we will provide that as well. Feel free to file an enhancement request if you are interested!Petr improved monitoring support which was added in Tyrus 1.6 – now there is a possibility to get the information about errors reported to the endpoints. Errors are collected per Exception type thrown, so you might get number of decoding issues, IOExceptions and other custom Throwables used in the endpoint implementation.Other than that, there were just bugfixes. Two of them are worth mentioning: Tyrus now supports close codes 1012 and 1013 (SERVICE RESTART and TRY AGAIN LATER). Both of these can be returned only from server endpoint. When client side will try to send those, they will be replaced with close code 1000.And the other bugfix is about SSL/TLS support in Java 7 AIO based client container – the issue manifested when bigger messages were sent from the client to server. The handling was not correct in this case and it could happen that the message was not completely sent.Complete list of changesTYRUS-313 Limiting opened connectionsTYRUS-319 Bug call EJB from WebSocketTYRUS-320 When put under heavy load by multiple clients, server throws an exception.TYRUS-321 tyrus-client incorrectly reports HTTP staus 500 for all non-101 responsesTYRUS-322 Some of session close-codes are not supportedTYRUS-324 Session.close() should close the connection without close reason.TYRUS-325 Server do not close session properly if non-instantiable endpoint class is providedTYRUS-326 Expose monitoring statistics about number of @OnError method invocationsTYRUS-327 JDK client container cannot handle “big” messages over SSL/TLSLinkIf you have any feedback, suggestions or improvement requests, please send us a note tousers@tyrus.java.net or create new issue at our JIRA instance.

This release cycle was shorter comparing to previous ones and the main purpose was to integrate and align with upper stack projects. Despite that fact there are some new features and bugfixes: What’s...

Tyrus 1.6

I’m pleased to announce that Tyrus 1.6 was released this week and there are some nice features and bugfixes in this release, so let me introduce most important ones.What’s new?First bigger addition is JDK Client Transport. We used exclusively Grizzly framework for handling transport layer on the client side and now we provide an option to switch to JDK 1.7 based transport. Main advantage of it is reduced size and number of jar files. The default transport is still based on Grizzly, so if you want to try JDK 1.7 AIO, you need to enable it explicitly. See JDK 7 client chapter in Tyrus documentation for more details. This feature was implemented by Petr Janouch, new Tyrus team member.Another important feature is monitoring server side resource utilisation and exposing this info as statistics via JMX beans. Currently available statistics are mostly about number and type of received and send messages, also there is higher level part which provides list of deployed endpoints and number of concurrent connected clients. If you want to try this out, see JMX Monitoring chapter in Tyrus user guide for configuration details. This feature was also contributed by Petr.Next in line is change related to an issue in JSR 356. Current version of Session interface does allow use of Lambda expressions when registering a message handler, but it does not work as expected. Problem is, that it just cannot work. The API forces implementation to get the generic type information during runtime, which is not always available (in Java). Most usecases do work fine, but one doesn’t – when the anonymous class implementation is replaced by Lambda expression, type information is lost. Tyrus now implements proposed solution, but to be able to access mentioned methods, you need to cast Session to TyrusSession. Then you need to provide type of the message handler (java.lang.Class) and the handler itself – since the type info is now separated, there is no need to get it from the message handler instance , thus it will work with any representation. We are working on porting this fix to the WebSocket API, stay tuned for more details.Last and in this case maybe least feature is WSADL. Don’t worry if you don’t know what that is – nobody does :). WSADL is XML (for now) descriptor of deployed application, currently providing only set of deployed endpoints (mainly because other information, like registered message handlers, is not that easy to get before client connects to the endpoint and can vary per Session). WSADL stands for WebSocket Application Descriptor Language and it is supposed to be the same as WADL is for RESTful webservices and WSDL for SOAP webservices. In case you want to test this feature, enableWSADL_SUPPORT (or see the test) and GET /contextPath/application.wsadl on your deployed Tyrus application.Complete list of changesTYRUS-301 Custom String encoder is not usedTYRUS-305 Add support for multiple client container to TestContainerTYRUS-311 Session timeout on client does not work when set in onOpen methodTYRUS-312 TyrusFuture.get(long,TimeUnit) does not honor Future.get(long,TimeUnit) contractTYRUS-293 Automatic heartbeat PINGTYRUS-259 Should produce a warning during deployment when OnMessage#maxMessageSize is larger than the value of org.glassfish.tyrus.servlet.incoming-buffer-sizeTYRUS-308 JDK Client transport – SSL supportTYRUS-309 JDK Client transport – Proxy supportTYRUS-318 Writer returned from BasicRemote.getSendWriter() throws NPE when flush is called more than once.TYRUS-314 Create WADL-like descriptor per deployed appTYRUS-317 Allow server configuration using WebSocketContainer or WebSocketAddOnTYRUS-302 Java 8 LambdaTYRUS-214 Expose monitoring API/statisticsTYRUS-299 Missing tyrus-container-grizzly-server in the release package WebSocket RI archiveTYRUS-233 Provide client transport based on plain JDKTYRUS-310 When max idle timeout is reset to 0, every received message or sent ping or pong causes an empty task to be scheduled and executedLinksIf you have any questions or comments or if you want to discuss anything related to Tyrus, easiest way to contact us is via users@tyrus.java.net mailing list.

I’m pleased to announce that Tyrus 1.6 was released this week and there are some nice features and bugfixes in this release, so let me introduce most important ones. What’s new? First bigger addition...

Starting with Oracle Coherence and Incubator projects

I had a chance to play with Oracle Coherence and even when everything seems to be documented, it took me a while to find all necessary informations to really get started, so I decided to share my steps. The main goal of this HOWTO will be building all samples from Coherence Incubator project, branch develop-12 (requires latest Coherence – 12.1.2).Getting CoherenceCoherence 12.1.2 can be downloaded from [here]. I’m using stand-alone install, but I’m pretty sure that everything should be mostly the same (from Coherence point of view). Downloaded zip archive contains coherence_121200.jar, so lets execute that. Oh, and I almost forgot – I’m using Java 8:1234$ java -versionjava version "1.8.0"Java(TM) SE Runtime Environment (build 1.8.0-b132)Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)And I’m on Mac OS X 10.9.2 (latest Mavericks). Installation process is pretty straightforward, you just execute java -jar ./coherence_121200.jar and use the wizard to install what you need. I choose samples to be included, but I won’t be referring to them in this post. Remember where you set your Oracle Home directory, it contains all the installed artefacts and we need to use it in next step.Let’s assume the installation is done without any issues (I did not experienced any) and we are in Oracle_Home directory somewhere on our file system. Another thing I forgot to mention – you will need Apache Maven to be able to compile/execute projects from Incubator. I have Maven 3.1.1:1234567$ mvn -vApache Maven 3.1.1 (0728685237757ffbf44136acec0402957f723d9a; 2013-09-17 17:22:22+0200)Maven home: /Users/pavel/opt/apache-maven-3.1.1Java version: 1.8.0, vendor: Oracle CorporationJava home: /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jreDefault locale: en_US, platform encoding: UTF-8OS name: "mac os x", version: "10.9.2", arch: "x86_64", family: "mac"Following information is taken from document available here:http://docs.oracle.com/middleware/1212/core/MAVEN.pdf.Firstly, you need to install oracle-maven-sync plugin. It will install Coherence into your local maven repository. It is capable to publishing these artefacts to your company maven repository or something like that, but that won’t be covered here. Please see linked document to see more details about it if required.The plugin gets installed by executing following command:1mvn install:install-file -DpomFile=./oracle_common/plugins/maven/com/oracle/maven/oracle-maven-sync/12.1.2/oracle-maven-sync.12.1.2.pom -Dfile=./oracle_common/plugins/maven/com/oracle/maven/oracle-maven-sync/12.1.2/oracle-maven-sync.12.1.2.jarI assume that this command is executed from Oracle_Home directory. You will need to adjust paths if that is not your case. Then you should see something similar to:12345678910111213141516[INFO] Scanning for projects...[INFO]                                                                         [INFO] ------------------------------------------------------------------------[INFO] Building Maven Stub Project (No POM) 1[INFO] ------------------------------------------------------------------------[INFO] [INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom ---[INFO] Installing /Users/pavel/coherence/Oracle/Middleware/Oracle_Home/oracle_common/plugins/maven/com/oracle/maven/oracle-maven-sync/12.1.2/oracle-maven-sync.12.1.2.pom to /Users/pavel/.m2/repository/com/oracle/maven/oracle-maven-sync/12.1.2-0-0/oracle-maven-sync-12.1.2-0-0.jar[INFO] Installing /Users/pavel/coherence/Oracle/Middleware/Oracle_Home/oracle_common/plugins/maven/com/oracle/maven/oracle-maven-sync/12.1.2/oracle-maven-sync.12.1.2.pom to /Users/pavel/.m2/repository/com/oracle/maven/oracle-maven-sync/12.1.2-0-0/oracle-maven-sync-12.1.2-0-0.pom[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 0.349s[INFO] Finished at: Fri Mar 21 15:26:37 CET 2014[INFO] Final Memory: 3M/81M[INFO] ------------------------------------------------------------------------Now we are ready to install Coherence binaries to our local maven repository:1Oracle_Home $ mvn -X com.oracle.maven:oracle-maven-sync:push -Doracle-maven-sync.oracleHome=.  -Doracle-maven-sync.testingOnly=falseOutput is quite long, but if you see “BUILD SUCESS”, you can be sure that coherence jars are now installed in local maven repository. If there is some error, it is most likely related to incorrect directory, so try to play with “-Doracle-maven-sync.oracleHome” property and get it right.Getting Coherence Incubator projectsThis is an easy part. Coherence incubator is hosted on github – you obviously need git for that.1git clone git@github.com:coherence-community/coherence-incubator.gitthats it. Git created directory coherence-incubator where all the projects are. Little inconvenient is that the version which we want to get is in the branch, so we need to execute:1git checkout origin/develop-12 -b develop-12Previous command checkouts remote branch “develop-12″ and saves it as local branch with the same name. It is not a must to create local branch, but it is easier to deal with that. Also, we will need to make some changes to get it running and you can store then in your local branch.I’m not exactly sure why, but the project references Coherence version 12.1.2-0-1, but oracle-maven-sync plugin installs version 12.1.2-0-0, so the project can’t compile without modifications. Also, coherence-jvisualvm references binaries deployed on netbeans maven repository which is not mentioned anywhere, so we need to add it for maven to be able to download these dependencies. My complete patch is:123456789101112131415161718192021222324diff --git a/pom.xml b/pom.xmlindex 785741e..c4d951a 100644--- a/pom.xml+++ b/pom.xml@@ -137,11 +137,18 @@ <junit.version>4.10</junit.version> <miglayout.version>3.6</miglayout.version> <mockito.version>1.9.0</mockito.version>-        <oracle.coherence.version>12.1.2-0-1</oracle.coherence.version>+        <oracle.coherence.version>12.1.2-0-0</oracle.coherence.version> <oracle.tools.version>1.2.2</oracle.tools.version> <powermock.version>1.4.12</powermock.version> </properties> +    <repositories>+        <repository>+            <id>netbeans</id>+            <url>http://bits.netbeans.org/nexus/content/repositories/visualvm</url>+        </repository>+    </repositories>+ <dependencyManagement> <dependencies> <dependency>Now, we are finally ready for1mvn -fae clean installThe “-fae” is here for trying to build everything possible, even when some project fails to build or test, which unfortunately happens. See my current results:12345678910111213141516171819202122232425262728[INFO] Coherence Incubator ............................... SUCCESS [1.284s][INFO] Coherence Incubator Common ........................ SUCCESS [30.717s][INFO] Coherence Incubator Command Pattern ............... SUCCESS [7.556s][INFO] Coherence Incubator Command Pattern (examples) .... SUCCESS [3.357s][INFO] Coherence Incubator Functor Pattern ............... SUCCESS [3.828s][INFO] Coherence Incubator Functor Pattern (examples) .... SUCCESS [2.577s][INFO] Coherence Incubator JVisualVM Plugin .............. SUCCESS [18.846s][INFO] Coherence Incubator Processing Pattern ............ SUCCESS [14.535s][INFO] Coherence Incubator Processing Pattern (examples) . SUCCESS [2.018s][INFO] Coherence Incubator Messaging Pattern ............. SUCCESS [8.903s][INFO] Coherence Incubator Messaging Pattern (functional tests)  SUCCESS [1:52.155s][INFO] Coherence Incubator Event Distribution Pattern .... SUCCESS [44.490s][INFO] Coherence Incubator Push Replication Pattern ...... SUCCESS [2.198s][INFO] Coherence Incubator Push Replication Pattern (functional tests)  FAILURE [6:49.643s][INFO] Coherence Incubator Push Replication Pattern (examples)  SUCCESS [1.645s][INFO] Coherence Incubator Push Replication Pattern *Web (examples)  SUCCESS [0.013s][INFO] Coherence Incubator Web Server .................... SUCCESS [2.058s][INFO] Coherence Incubator Web Application ............... SUCCESS [6.210s][INFO] Coherence Incubator Web Application Test .......... FAILURE [1:27.214s][INFO] Coherence Incubator Distribution .................. SUCCESS [13.540s][INFO] Coherence Incubator Site .......................... SUCCESS [0.019s][INFO] ------------------------------------------------------------------------[INFO] BUILD FAILURE[INFO] ------------------------------------------------------------------------[INFO] Total time: 12:53.648s[INFO] Finished at: Fri Mar 21 16:30:09 CET 2014[INFO] Final Memory: 58M/210M[INFO] ------------------------------------------------------------------------Anyway, as you can see, most of the projects can compile and are working properly. I was interested mainly in Messaging pattern, which works as expected, so I did not do any further inquiries about in Replication pattern and Web app tests.And that’s it. If you are interested in any of these patterns or project, see sources and tests, there are usually “hello world” like samples which are perfect for learning. Also, if you happen to discover the reason for test failures I’m getting, feel free to add comment or send me a note to pavel.bucek [at] oracle.com and I’ll update the article.

I had a chance to play with Oracle Coherence and even when everything seems to be documented, it took me a while to find all necessary informations to really get started, so I decided to share my...

WebSocket API in JDK 8 - MessageHandler issue

JDK 8 is not yet released and it is already causing some headaches for JSR 356 implementors. The issue described in this article will be about the most famous and anticipated JDK 8 feature – lambda expressions and its impact to one part of WebSocket API.Lambda expressions usable in WebSocket API can be diminished to just a replacement for standard anonymous classes; there might be some places where you can use method references, but not in the case of message handler. Following text is mainly about addMessageHandler method:123public interface Session extends Closeable { void addMessageHandler(MessageHandler handler) throws IllegalStateException;}There are multiple use cases when addMessageHandler method is used – for example, in any endpoint based on programmatic API, which is typically true on client side. Then you have code like:1234567891011public class MyEndpoint extends Endpoint { @Override public void onOpen(Session session, EndpointConfig config) { session.addMessageHandler(new MessageHandler.Whole<String>() { @Override public void onMessage(String message) { // handle message } }); }}which always works as expected. JDK 8 introduces lambda expressions which can (not only!) replace too verbose anonymous classes, when they have only single method – which is true for MessageHandler.Whole interface. So when that code is opened in IDE supporting Java 8, it will usually say something like “anonymous class can be replaced with lambda expression” and recommends that action to be done. The resulting code will be:12345678public class MyEndpoint extends Endpoint { @Override public void onOpen(javax.websocket.Session session, EndpointConfig config) { session.addMessageHandler((MessageHandler.Whole<String>) message -> { // handle message }); }}It is nicer, part of the information is hidden, but my guess is it might not be seen as a drawback for most cases. And 3 lines of code were saved, so thumbs up! Well.. there is the last thing.. it doesn’t work.Lambda expressions are not anonymous classes. Anonymous class can be replaced by using lambda expression and it still compiles, but the generic parameter is lost, or at least there is no way how to obtain it via standard reflection API. And that is the problem for any JSR 356 implementation – type parameter here is used for selecting appropriate Decoder (another part of the API). Any lambda expression used instead regular generic anonymous class will be treaded as MessageHandler.Whole<Object>.What can we do with this? Surprisingly, not much. I will try to file a backwards compatibility issue/challenge agains JDK 8, but from the initial reactions on jdk8-dev mailing list, it does not seem like something anybody is willing to fix. There is one nice constructive proposal from Simone Bordet, which would at least make the variant with lambda not compilable. That would be great workaround (which will require WebSocket API 1.0.1 release and potentially changes in other APIs), but I still consider this being an issue which should be fixed in more generic way. And last but not least – I don’t think that new version of JDK should break any existing working API.I’ll keep this post updated whenever I got additional information. Feel free to comment or suggest a solution!EDIT:Credit for discovering this issue should go to user ayyrk, reporter of TYRUS-302

JDK 8 is not yet released and it is already causing some headaches for JSR 356 implementors. The issue described in this article will be about the most famous and anticipated JDK 8 feature – lambda...

Tyrus 1.5

New version of Tyrus was released today, so let’s do a quick summary of what is new compared to previous version and so on. What’s new? maven archetype (echo sample). Tyrus Client can run on Android. Tyrus Client re-connect feature. Maven archetype was (finally) added, so if you want to generate simple application, test it and maybe start playing with the code and modifying it to something more complex, you can. All you need is maven and little space on your hard drive. Then you can execute following command: 1 2 3 4 mvn archetype:generate -DarchetypeArtifactId=tyrus-archetype-echo \ -DarchetypeGroupId=org.glassfish.tyrus.archetypes -DinteractiveMode=false \ -DgroupId=com.example -DartifactId=echo -Dpackage=com.example \ -DarchetypeVersion=1.5 and the project should be created. What’s fixed? Close reason for dropped connection is now 1006, as it should be. Standalone Server is not leaking daemon threads any more. Java SE 8 runtime issues. “Host” header parsing issue which caused failed handshakes when using IPv6 localhost address ([::1]).  Internal InputStream implementation now correctly returns ‘-1′ to InputStream#read() only when end of input is reached. Thanks Raghu for contributing the fix! Java SE 8 related issue is worth a short explanation, since the change introduced by this fix goes beyond SE 8. Original problem was about some bug in Java SE 7 which somehow corrected Tyrus behaviour, so it was not noticed by our tests – bridge methods are not returned from Class.getMethods() call there. This was fixed in Java SE 8 and it caused some troubles in Tyrus implementation, because we just did not expect them to be returned. The other part of this issue was correcting Tyrus in terms of handling inherited methods. JSR 356 describes how these should be handled in little bit cryptic way, but it basically states that annotations are not inherited, which is already defined in Java language specification. Unfortunately, Tyrus prior this version was considering annotated methods (@OnOpen, @OnMessage, …) only from the very same class as the registered one, so inherited methods were always ignored. This is now changed, so you can have something like: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class BaseEndpoint { @OnOpen public void onOpen(Session session) throws IOException { // do something. } } @ServerEndpoint("/echo") public class EchoEndpoint extends BaseEndpoint { @OnMessage public void echo(Session session, String message) throws IOException { // do something else. } } both methods – onOpen and onMessage will be considered as part of EchoEndpoint class. Please note that annotations are still not inherited, so if you for example declare BaseEndpoint class as abstract with onOpen method annotated with @OnOpen, overriding method won’t be called by Tyrus unless you “re-add” @OnOpen annotation to new method: 1 2 3 4 5 6 7 8 9 10 11 12 13 public abstract class BaseEndpoint { public abstract void onOpen(Session session) throws IOException; } @ServerEndpoint("/echo") public class EchoEndpoint extends BaseEndpoint { @OnOpen // this has to be here! @Override public void onOpen(Session session) throws IOException { // do something. } } Feel free to ask here or send us a note to users@tyrus.java.net if you have any questions related to this release or anything related to our WebSocket implementation. Links Tyrus homepage Tyrus JIRA

New version of Tyrus was released today, so let’s do a quick summary of what is new compared to previous version and so on. What’s new? maven archetype (echo sample). Tyrus Client can run on Android. Tyru...

WebSocket Client Reconnect

Another new feature was recently added to Tyrus (Java API for WebSocket Reference Implementation): Client ReconnectHandler. Some client use cases require almost persistent client-to-server connection and don’t really care about lower layer issues, like unstable internet connection.Tyrus Client now include possibility of registering ReconnectHandler, which can help with these scenarios. Let’s see ReconnectHandler declaration:12345678910public class ReconnectHandler { public boolean onDisconnect(CloseReason closeReason) { return false; } public boolean onConnectFailure(Exception exception) { return false; }}Method onDisconnect is executed whenever client endpoint @OnClose annotated method is called, method onConnectFailure is executed whenever client has some troubles connecting to remote endpoint (network issues, server returning HTTP Status 500, …). Both methods can return boolean value, which indicates whether client should try to reconnect or not.It is perfectly fine to wait in any of these methods for some time – I would recommend it for onConnectFailure, because there usually is some reason for network failure and repeating requests without any delay can prolong them or even make them worse. Also I would recommend include some kind of counter, which would set the number of reconnect attempts.Example implementation could look like:12345678910111213141516171819202122232425262728293031323334ClientManager client = ClientManager.createClient();ClientManager.ReconnectHandler reconnectHandler = new ClientManager.ReconnectHandler() { private int counter = 0; @Override public boolean onDisconnect(CloseReason closeReason) { counter++; if (counter <= 3) { System.out.println("### Reconnecting... (reconnect count: " + counter + ")"); return true; } else { return false; } } @Override public boolean onConnectFailure(Exception exception) { counter++; if (counter <= 3) { System.out.println("### Reconnecting... (reconnect count: " + counter + ") " + exception.getMessage()); // Thread.sleep(...) or something other "sleep-like" expression can be put here - you might want // to do it here to avoid potential DDoS when you don't limit number of reconnects. return true; } else { return false; } }}; client.getProperties().put(ClientManager.RECONNECT_HANDLER, reconnectHandler); client.connectToServer(...)

Another new feature was recently added to Tyrus (Java API for WebSocket Reference Implementation): Client ReconnectHandler. Some client use cases require almost persistent client-to-server connection...

Updating Tyrus in Glassfish

This article is inspired by similar one about Jersey and will provide similar information. Thanks to Michal for creating such comprehensive instructions. Fortunately, Tyrus does not depend on HK2 so the task here is lot easier. To be absolutely honest, I did expect some issues with Grizzly dependency in Tyrus client, but changes are backwards compatible (applies to Tyrus 1.4), so you can update Tyrus to any version of released Glassfish very easily. Which version of Tyrus am I using? You can get this from tyrus-core.jar manifest: 1 2 $ unzip -p $GLASSFISH_HOME/glassfish/modules/tyrus-core.jar META-INF/MANIFEST.MF | grep Bundle-Version Bundle-Version: 1.0.0 This means you are using Tyrus 1.0. I strongly recommend to upgrade. Latest version now is Tyrus 1.4 and the output will look like: 1 2 $ unzip -p $GLASSFISH_HOME/glassfish/modules/tyrus-core.jar META-INF/MANIFEST.MF | grep Bundle-Version Bundle-Version: 1.4.0 Glassfish distributions Table below contains overview of current Glassfish 4.x builds: Glassfish version Download link Tyrus version 4.0 (Java EE 7 RI) [download] 1.0 4.0.1 b01 [download] 1.0 4.0.1 b02 [download] 1.2.1 4.0.1 b03 [download] 1.2.1 4.0.1 latest nightly [download] latest Updating to Tyrus 1.4 1 2 3 4 5 6 7 8 9 10 11 $ wget http://search.maven.org/remotecontent?filepath=org/glassfish/tyrus/bundles/websocket-ri-archive/1.4/websocket-ri-archive-1.4.zip -O ./websocket-ri-archive-1.4.zip $ rm $GLASSFISH_HOME/glassfish/modules/tyrus-*jar $ unzip -j ./websocket-ri-archive-1.4.zip "websocket-ri-archive-1.4/lib/*" -d $GLASSFISH_HOME/glassfish/modules/ Archive:  ./websocket-ri-archive-1.4.zip inflating: [path]/modules/tyrus-client-1.4.jar inflating: [path]/modules/tyrus-container-glassfish-cdi-1.4.jar inflating: [path]/modules/tyrus-container-grizzly-client-1.4.jar inflating: [path]/modules/tyrus-container-servlet-1.4.jar inflating: [path]/modules/tyrus-core-1.4.jar inflating: [path]/modules/tyrus-server-1.4.jar inflating: [path]/modules/tyrus-spi-1.4.jar And that’s it. Remember to restart Glassfish instance after replacing Tyrus jar files. Note As of now (1/24/2013) latest nightly build of Glassfish contains Tyrus 1.3.3. Next nightly should contain latest Tyrus release – version 1.4. Links Tyrus homepage Tyrus JIRA

This article is inspired by similar one about Jersey and will provide similar information. Thanks to Michal for creating such comprehensive instructions. Fortunately, Tyrus does not depend on HK2 so...

WebSocket Client on Android – Tyrus

Running some Java EE libraries or frameworks in non-standard VM is not an uncommon task and same is for Tyrus. I have to admit that this task was driven mainly by issue report TYRUS-256 from Reza. There is no official support from Tyrus running on Dalvik and I'm not even sure if it is a good idea, but important fact is that it works and you can do it if you want :-). Whole issue which blocked runtime from being able to run on Android was in usage of javax.naming.InitialContext class. There is no simple alternative to it, but fortunately there is always a possibility to do little bit of reflection hacking to get rid of the dependency if it's not there. The rest was only about creating the sample application and testing it on my phone, which was not that hard. I have to give kudos to IntelliJ IDEA team for their support, but not for Android Studio - it uses gradle as build tool and it seems like you cannot include java library because android plugin clashes with java plugin (I'm not very familiar with gradle as you might have noticed). Using and build script and build in support was better for my task. The application I used for testing is available on github in my personal workspace: https://github.com/pavelbucek/tyrus-client-android-test. Feel free to test it and/or provide pull requests. I would be particularly interested in gradle build script. That's it for today. If you are using Tyrus on Android or if you have any related comments, please share them with us on Tyrus mailing list or as an enhancement request.

Running some Java EE libraries or frameworks in non-standard VM is not an uncommon task and same is for Tyrus. I have to admit that this task was driven mainly by issue report TYRUS-256 from Reza....

Tyrus 1.4

I’m pleased to announce that Tyrus 1.4 was released today. It contains all features mentioned recently on my blog: Extensions support (including compression extensions implementation), shared client container and many other improvements and bug fixes. Binaries will be available on maven central repository soon and Tyrus 1.4 will be integrated into Glassfish trunk. As always, feel free to contribute! You can file an enhancement or a bug or just ask if there is something unclear in the documentation. Release notes Bugs [TYRUS-136] – org.glassfish.tyrus.server.Server does not stop correctly when DeploymentException is thrown [TYRUS-263] – SSL via HTTP PROXY – wss://echo.websocket.org Handshake error. “Response code was not 101: 200″ [TYRUS-269] – Parallel connection to ServerEndpoint with URI template mix up response to client instances … [TYRUS-270] – The title of file README.html of Draw sample is mis-typed from “Draw Sample” to “Chat Sample” [TYRUS-271] – “?null” is added to every request without query params [TYRUS-272] – TyrusServerConfiguration incompatible with jetty’s jsr 356 implementation. [TYRUS-273] – EJB component provider needs to provide method which will be invoked. [TYRUS-275] – Tyrus client has bug causing limitation of # of open web sockets [TYRUS-276] – Session accepts messages after idle timeout (@OnMessage is triggered) [TYRUS-277] – session.setMaxIdleTimeout(0) does not reset/cancel the timeout [TYRUS-280] – Extension parsed does not allow parameter without value [TYRUS-281] – Client does CDI/EJB lookup [TYRUS-282] – Session.setMaxIdleTimeout(..) does not work as expected for negative values [TYRUS-288] – WebSocket connections are automatically closed after 30 idle seconds in standalone mode Improvements [TYRUS-56] – content root directory configuration in Server class for static content [TYRUS-160] – Tyrus tests won’t compile with JDK 1.6 [TYRUS-183] – UTF8 validation logic should be separated from frame parsing [TYRUS-265] – Improve GrizzlyWriter implementation [TYRUS-266] – Support for WebSocket extensions [TYRUS-268] – In-memory transport for testing / performance analysis New Features [TYRUS-193] – Support Tyrus with different transports [TYRUS-283] – CompressionExtension (permessage-compression) [TYRUS-286] – Shared client container improvement (stop when there is no open session) [TYRUS-287] – Cannot create non-daemon threads with Tyrus server standalone mode Tasks [TYRUS-246] – Investigate and fix issues related to ServletTest#testWebSocketBroadcast [TYRUS-264] – Client SPI

I’m pleased to announce that Tyrus 1.4 was released today. It contains all features mentioned recently on my blog: Extensions support (including compression extensions implementation), shared client...

WebSocket Extensions in Tyrus

There is always room for another experimental feature :-) This one is maybe little less experimental than broadcast support, but please implement presented APIs with one important fact in your mind – it can change any time. What is WebSocket Extension? You can think of WebSocket Extension as a filter, which processes all incoming and outgoing frames. Frame is the smallest unit in WebSocket protocol which can be transferred on the wire – it contains some some metadata (frame type, opcode, payload length, etc.) and of course payload itself. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-------+-+-------------+-------------------------------+|F|R|R|R| opcode|M| Payload len | Extended payload length ||I|S|S|S| (4) |A| (7) | (16/64) ||N|V|V|V| |S| | (if payload len==126/127) || |1|2|3| |K| | |+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +| Extended payload length continued, if payload len == 127 |+ - - - - - - - - - - - - - - - +-------------------------------+| |Masking-key, if MASK set to 1 |+-------------------------------+-------------------------------+| Masking-key (continued) | Payload Data |+-------------------------------- - - - - - - - - - - - - - - - +: Payload Data continued ... :+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +| Payload Data continued ... |+---------------------------------------------------------------+ Figure taken from RFC 6455 If you are interested about some more details related to WebSocket protocol specification, please see linked RFC document (RFC 6455). What can be achieved by WebSocket Extension? Almost everything. You can change every single bit of incoming or outgoing frame, including control frames (close, ping and pong). There are some RFC drafts trying to standardise extensions like per message compression (used to be per frame compression) and multiplexing extension (now expired). Tyrus already has support for per message compression extension and exposes interfaces which allow users to write custom extensions with completely different functionality. When should I consider implementing WebSocket Extensions? This is maybe the most important question. WebSocket Extensions can do almost everything, but you should not use them for use cases achievable by other means. Why? Majority of WebSocket use cases are about communication with browsers and javascript client cannot really influence which exception is going to be used. Browser must support your particular extension (by default or it can be enabled by some custom module). You can easily use custom extension when using Tyrus java client, so if there is no browser interaction in your application, it should be easier to distribute your extensions to involved parties and you might lift the threshold when deciding whether something will be done by extension or by application logic. Java API for WebSocket and Extensions API currently contains following extension representation (javadoc removed): 1 2 3 4 5 6 7 8 9 10 public interface Extension { String getName(); List getParameters(); interface Parameter { String getName(); String getValue(); } } and the specification (JSR 356) limits extension definition only for handshake purposes. To sum that up, users can only declare Extension with static parameters (no chance to set parameters based on request extension parameters) and that’s it. These extensions don’t have any processing part, so the work must be done somewhere else. As you might already suspect, this is not ideal state. Usability of extensions specified like this is very limited, it is basically just a marker class which has some influence on handshake headers. You can get list of negotiated extensions in the runtime (Session.getNegotiatedExtensions()) but there is no way how you could access frame fields other than payload itself. Proposed Extension API I have to repeat warning already presented at the start of this blog post – anything mentioned below might be changed without notice. There are some TODO items which will most likely require some modification of presented API, not to mention that RFC drafts of WebSocket Extensions are not final yet. There might be even bigger modification needed – for example, multiplexing draft specifies different frame representation, use of RSV bits is not standardised etc. So please take following as a usable proof of concept and feel free to use them in agile projects. Firstly, we need to create frame representation. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class Frame { public boolean isFin() { .. } public boolean isRsv1() { .. } public boolean isRsv2() { .. } public boolean isRsv3() { .. } public boolean isMask() { .. } public byte getOpcode() { .. } public long getPayloadLength() { .. } public int getMaskingKey() { .. } public byte[] getPayloadData() { .. } public boolean isControlFrame() { .. } public static Builder builder() { .. } public static Builder builder(Frame frame) { .. } public final static class Builder { public Builder() { .. } public Builder(Frame frame) { .. } public Frame build() { .. } public Builder fin(boolean fin) { .. } public Builder rsv1(boolean rsv1) { .. } public Builder rsv2(boolean rsv2) { .. } public Builder rsv3(boolean rsv3) { .. } public Builder mask(boolean mask) { .. } public Builder opcode(byte opcode) { .. } public Builder payloadLength(long payloadLength) { .. } public Builder maskingKey(int maskingKey) { .. } public Builder payloadData(byte[] payloadData) { .. } } } This is pretty much straightforward copy of frame definition mentioned earlier. Frame is designed as immutable, so you cannot change it in any way. One method might be recognised as mutable – getPayloadData() – returns modifiable byte array, but it is always new copy, so the original frame instance remains intact. There is also a Frame.Builder for constructing new Frame instances, notice it can copy existing frame, so creating a new frame with let’s say RSV1 bit set to “1″ is as easy as: 1 Frame newFrame = Frame.builder(originalFrame).rsv1(true).build(); Note that there is only one convenience method: isControlFrame. Other information about frame type etc needs to be evaluated directly from opcode, simply because there might not be enough information to get the correct outcome or the information itself would not be very useful. For example: opcode 0×00 means continuation frame, but you don’t have any chance to get the information about actual type (text or binary) without intercepting data from previous frames. Consider Frame class as as raw as possible representation.isControlFrame can be also gathered from opcode, but it is at least always deterministic and it will be used by most of extension implementations. It is not usual to modify control frames as it might end with half closed connections or unanswered ping messages. New Extension representation needs to be able to handle extension parameter negotiation and actual processing of incoming and outgoing frames. It also should be compatible with existing javax.websocket.Extension class, since we wan’t to re-use existing registration API and be able to return new extension instance included in response fromSession.getNegotiatedExtensions():List<Extension> call. Consider following: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public interface ExtendedExtension extends Extension { Frame processIncoming(ExtensionContext context, Frame frame); Frame processOutgoing(ExtensionContext context, Frame frame); List onExtensionNegotiation(ExtensionContext context, List requestedParameters); void onHandshakeResponse(ExtensionContext context, List responseParameters); void destroy(ExtensionContext context); interface ExtensionContext { Map<String, Object> getProperties(); } } ExtendedExtension is capable of processing frames and influence parameter values during the handshake. Extension is used on both client and server side and since the negotiation is only place where this fact applies, we needed to somehow differentiate these sides. On server side, only onExtensionNegotiation(..) method is invoked and client side hasonHandshakeResponse(..). Server side method is a must, client side could be somehow solved by implementing ClientEndpointConfig.Configurator#afterResponse(..) or calling Session.getNegotiatedExtenions(), but it won’t be as easy to get this information back to extension instance and even if it was, it won’t be very elegant. Also, you might suggest replacing processIncoming and processOutgoing methods by just oneprocess(Frame) method. That is also possible, but then you might have to assume current direction from frame instance or somehow from ExtenionContext, which is generally not a bad idea, but it resulted it slightly less readable code. Last but not least is ExtensionContext itself and related lifecycle method. OriginalExtension from javax.websocket is singleton and ExtendedExtension must obey this fact. But it does not meet some requirements we stated previously, like per connection parameter negotiation and of course processing itself will most likely have some connection state. Lifecycle of ExtensionContext is defined as follows: ExtensionContextinstance is created right before onExtensionNegotiation (server side) oronHandshakeResponse (client side) and destroyed after destroy method invocation. Obviously, processIncoming or processOutgoing cannot be called before ExtensionContextis created or after is destroyed. You can think of handshake related methods as @OnOpenand destroy as @OnClose. For those more familiar with WebSocket protocol: process*(ExtensionContext, Frame) is always invoked with unmasked frame, you don’t need to care about it. On the other side, payload is as it was received from the wire, before any validation (UTF-8 check for text messages). This fact is particularly important when you are modifying text message content, you need to make sure it is properly encoded in relation to other messages, because encoding/decoding process is stateful – remainder after UTF-8 coding is used as input to coding process for next message. If you want just test this feature and save yourself some headaches, don’t modify text message content or try binary messages instead. Code sample Let’s say we want to create extension which will encrypt and decrypt first byte of every binary message. Assume we have a key (one byte) and our symmetrical cipher will be XOR. (Just for simplicity (a XOR key XOR key) = a, so encrypt() and decrypt() functions are the same). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 public class CryptoExtension implements ExtendedExtension { @Override public Frame processIncoming(ExtensionContext context, Frame frame) { return lameCrypt(context, frame); } @Override public Frame processOutgoing(ExtensionContext context, Frame frame) { return lameCrypt(context, frame); } private Frame lameCrypt(ExtensionContext context, Frame frame) { if(!frame.isControlFrame() && (frame.getOpcode() == 0x02)) { final byte[] payloadData = frame.getPayloadData(); payloadData[0] ^= (Byte)(context.getProperties().get("key")); return Frame.builder(frame).payloadData(payloadData).build(); } else { return frame; } } @Override public List onExtensionNegotiation(ExtensionContext context, List requestedParameters) { init(context); // no params. return null; } @Override public void onHandshakeResponse(ExtensionContext context, List responseParameters) { init(context); } private void init(ExtensionContext context) { context.getProperties().put("key", (byte)0x55); } @Override public void destroy(ExtensionContext context) { context.getProperties().clear(); } @Override public String getName() { return "lame-crypto-extension"; } @Override public List getParameters() { // no params. return null; } } You can see that ExtendedExtension is slightly more complicated that original Extension so the implementation has to be also not as straightforward.. on the other hand, it does something. Sample code above shows possible simplification mentioned earlier (one process method will be enough), but please take this as just sample implementation. Real world case is usually more complicated. Now when we have our CryptoExtension implemented, we want to use it. There is nothing new compared to standard WebSocket Java API, feel free to skip this part if you are already familiar with it. Only programmatic version will be demonstrated. It is possible to do it for annotated version as well, but it is little bit more complicated on the server side and I want to keep the code as compact as possible. Client registration 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ArrayList extensions = new ArrayList(); extensions.add(new CryptoExtension()); final ClientEndpointConfig clientConfiguration = ClientEndpointConfig.Builder.create() .extensions(extensions).build(); WebSocketContainer client = ContainerProvider.getWebSocketContainer(); final Session session = client.connectToServer(new Endpoint() { @Override public void onOpen(Session session, EndpointConfig config) { // ... } }, clientConfiguration, URI.create(/* ... */)); Server registration: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class CryptoExtensionApplicationConfig implements ServerApplicationConfig { @Override public Set getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses) { Set endpointConfigs = new HashSet(); endpointConfigs.add( ServerEndpointConfig.Builder.create(EchoEndpoint.class, "/echo") .extensions(Arrays.asList(new CryptoExtension())).build() ); return endpointConfigs; } @Override public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) { // all scanned endpoints will be used. return scanned; } } public class EchoEndpoint extends Endpoint { @Override public void onOpen(Session session, EndpointConfig config) { // ... } } CryptoExtensionApplicationConfig will be found by servlets scanning mechanism and automatically used for application configuration, no need to add anything (or even have)web.xml. Per Message Deflate Extension The original goal of whole extension support was to implement Permessage extension as defined in draft-ietf-hybi-permessage-compression-15 and we were able to achieve that goal. Well, not completely, current implementation ignores parameters. But it seems like it does not matter much, it was tested with Chrome and it works fine. Also it passes newest version of Autobahn test suite, which includes tests for this extension. PerMessageDeflateExtension.java (compatible with draft-ietf-hybi-permessage-compression-15, autobahn test suite) XWebKitDeflateExtension.java (compatible with Chrome and Firefox – same as previous, just different extension name) PerMessageDeflateTest.java TODO There are some things which needs to be improved or specified to make this reliable and suitable for real world use. It might not seem as big feature, but it enables lots of use cases not defined in original specification and some of them are clashing little bit, so for now, I kept everything as it was when you are not using extended extensions. Everything mentioned in this article is already available in Tyrus 1.4-SNAPSHOT and will be part of 1.4 release. Extension / Frame Validation Frame representation – frame types Frame representation – payload representation Frame representation – masking – remove? (current state: container responsibility) Exception handling – processIncoming and processOutgoing methods (current state: exceptions are logged) Exception handling – onExtensionNegotiation Possibility to reject negotiation extension in onExtensionNegotiation (based on extension params) Extension ordering (current state: handshake response header order) Extension resource validation (two extensions using same RSV bit(s) cannot be negotiated) PerMessageDeflate – parameters MultiplexingExtension – implement when (if) ready Conclusion There is still lots of decisions to be made and things to do, but it seems like we can implement usable extensions which are supported by newer versions of browsers and containers. PerMessageDeflate extension is nice example of handy feature which can save significant resources. Links Frame.java ExtendedExtension.java Tyrus homepage Tyrus JIRA

There is always room for another experimental feature :-) This one is maybe little less experimental than broadcast support, but please implement presented APIs with one important fact in your mind –...

Tyrus client – shared container

Current “trunk” version contains one notable feature – shared client container. It can save significant portion of resources on client side if you are creating lots of client connections and there is almost no drawback. This feature was added as a response to TYRUS-275 and it somehow copies what other containers are doing in the JRS 356 implementation. Specification does not really state which system resources should be reusable (that’s ok, I think this is implementation detail), but it also does not take care of thread pool related settings, which might introduce some inconsistencies among implementations. WebSocket client implementation in Tyrus re-creates client runtime wheneverWebSocketContainer#connectToServer is invoked. This approach gives us some perks like out-of-the-box isolation and relatively low thread count (currently we have 1 selector thread and 2 worker threads). Also it gives you the ability to stop the client runtime – one Session instance is tied to exactly one client runtime, so we can stop it when Session is closed. This seems as a good solution for most of WebSocket client use cases – you usually use java client from application which uses it for communicating with server side and you typically don’t need more than 10 instances (my personal estimate is that more than 90% applications won’t use more than 1 connection). There are several reasons for it – of it is just a client, it needs to preserve server resources – one WebSocket connection means one TCP connection and we don’t really want clients to consume more than needed. Previous statement may be invalidated by WebSocket multiplexing extension, but for now, it is still valid. On the other hand, WebSocket client implementations in some other containers took another (also correct) approach – they share client runtime for creating all client connections. That means they might not have this strict one session one runtime policy, they cannot really give user way how he to control system resources, but surely it has another advantage – it can handle much more opened connections. Thread pools are share among client sessions which may or may not have some unforeseen consequences, but if its implemented correctly, it should outperform Tyrus solution mentioned in previous paragraph in some use cases, like the one mentioned in TYRUS-275 - performance tests. Reported created simple program which used WebSocket API to create clients and connect to remote endpoint and he measured how many clients can he create (or in other words: how many parallel client connection can be created; I guess that original test case is to measure possible number of concurrent clients on server side, but that does not really matter for this post). Tyrus implementation loose compared to some other and it was exactly because it did not have shared client runtime capability. I hope that common grounds are established and explained and we can take more detailed look to Tyrus implementation of shared client runtime. Default client implementation is using Grizzly as client container and all the work was done there – client SPI did not need to be changed (phew), so basically there are only some static fields and some basic synchronisation required for this to work. Grizzly part was really easy, it is only about sharing the instance of created TCPNIOTransport. Another small enhancement related to this feature is shared container timeout – if shared client runtime does not handle any connections for set period of time, it will just shutdown and clear all used resources. Everything will be automatically recreated when needed. Default value for this is 30 seconds. How can you use this feature? 1 2 3 ClientManager client = ClientManager.createClient(); client.getProperties().put(GrizzlyClientContainer.SHARED_CONTAINER, true); And you are done. You might also want to specify container idle timeout: 1 client.getProperties().put(GrizzlyClientContainer.SHARED_CONTAINER_IDLE_TIMEOUT, 5); and last but not least, you might want to specify thread pool sizes used by shared container (please use this feature only when you do know what are you doing. Grizzly by default does not limit max number of used threads, so if you do that, please make sure thread pool size fits your purpose): 1 2 client.getProperties().put(GrizzlyClientSocket.SELECTOR_THREAD_POOL_CONFIG, ThreadPoolConfig.defaultConfig().setMaxPoolSize(3)); client.getProperties().put(GrizzlyClientSocket.WORKER_THREAD_POOL_CONFIG, ThreadPoolConfig.defaultConfig().setMaxPoolSize(10)); And that’s it for today. You can use mentioned features with Tyrus 1.4-SNAPSHOT and newer, feel free to comment this post or drop me a note to users@tyrus.java.net with any feedback or suggestion how this can be improved. Links Tyrus homepage Tyrus JIRA

Current “trunk” version contains one notable feature – shared client container. It can save significant portion of resources on client side if you are creating lots of client connections and there is...

Tyrus container SPI

This blog post will be little more technical and insightful into Tyrus internals and won’t be as useful for common users which are just trying to use it for creating their web socket endpoint. I will describe how you can run Tyrus client or server side on virtually any container with a little help. We will start with Client side – it is a little bit simpler I think – then go through Server side and at the end I will present simple in-memory container which is already present in Tyrus workspace and is part of latest release (1.3.3). Let me start with little background. Tyrus originally started as something built on top of project Grizzly, which serves as NIO layer in Glassfish. Grizzly had (still has) its own API which supports creating web socket endpoints and does even have client implementation. Then JSR 356 was started, Tyrus (originally called “websocket-sdk“) was created and it was just a simple adaptation layer on top of Grizzly container. Then it was decided that this JSR will  be part of Java EE 7. This brought much more visibility to this project and also some more requirements. Tyrus was required to run on any Java EE 7 compliant container, utilising Servlet 3.1 API (upgrade mechanism, non-blocking reads and writes). So another layer was created, this time slightly more low level, because Tyrus was required to handle reading and writing, something which was previously handled by Grizzly. The decision was made, Tyrus adopted some Grizzly code and the Container SPI started to form. Tyrus still kept Grizzly container support and it was able to work with Servet 3.1 API as well. (Just for the sake of completeness – this is about server side. Client part always exclusively used Grizzly as container). Then another requirement came – it was decided that Tyrus will be integrated into WebLogic server (it will be part of upcoming 12.1.3 release). Initial integration used lots of Tyrus internals which was kind of scary, because future integrations might require significant amount of time, especially when considering some not trivial features we plan for Tyrus (Extension support, subprotocols, etc). WebLogic 12.1.3 does not contain Grizzly nor Servlet 3.1 implementation, so we needed to have something which will be more stable than any other Tyrus internal class. Small note – this is final version of the SPI for now, it does not mean that it won’t change. We might need to extend it to support some new features or fix bugs. Also there is no discovery mechanism in place (yet), so implementors of these SPI will have direct dependency on some Tyrus internal class(es). These internal classes (TyrusWebSocketEngine, etc.) may be changed, but there is higher resistance mode for these, so it shouldn’t be done that often and if we can achieve backwards compatibility, we will. Discovery mechanism will most likely be introduced sometime later.. Enough with this history lesson, let’s get to the code part. Client SPI Client side container is basically only about implementing ClientContainer. Method openClientSocket will be called when ClientManager needs to connect to server endpoint and following sequence of calls is then expected: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class MyClientContainer implements ClientContainer { @Override public void openClientSocket(String url, ClientEndpointConfig cec, Map<String, Object> properties, ClientEngine clientEngine) throws DeploymentException, IOException { // initialize container, open connection final UpgradeRequest upgradeRequest = clientEngine.createUpgradeRequest(URI.create(url), new ClientEngine.TimeoutHandler() { ... }); // handle ssl and proxies here if required // write upgradeRequest // wait for response, create UpgradeResponse instance // create custom writer // create connection close listener // get Connection final Connection connection = clientEngine.processResponse( upgradeResponse, writer, closeListener ); } void processIncomingData(ByteBuffer data) { // get read handler final ReadHandler readHandler = connection.getReadHandler(); // call readHandler.handle on anything received readHandler.handle(data); } } That’s it. ReadHandler and Writer classes are pretty straightforward, so no need to go there, only last important thing is how we can register ClientContainer so the runtime will use it. Here you need to implement ContainerProvider from JSR-356 API: 1 2 3 4 5 6 7 // registered via META-INF/services public class MyContainerProvider extends ContainerProvider { @Override protected WebSocketContainer getContainer() { return ClientManager.createClient(MyClientContainer.class.getName()); } } Note “registered via META-INF/services” means that you need to provide file named “javax.websocket.ContainerProvider” under META-INF/services directory and put fully classified class name of your implementation. Then all applications which run “ContainerProvider.getWebSocketContainer();” will get the client using your ClientContainer to make connections. You can always just use ClientManager directly if you need (it implements WebSocketContainer, so it is only about modifying the initial client instantiation). Server SPI Server side is slightly more complicated for obvious reasons – server bootstrap is more complicated – more than one endpoint can be deployed. Also it needs to handle more than one connection and there are some features defined in JSR 356 which complicate things a little bit. Firstly you need to create ServerContainer. Tyrus has its own implementation – TyrusServerContainer. It has two abstract methods which needs to be implemented. Tyrus also comes to help you – these methods are implemented in TyrusWebSocketEngine, so you most likely will create instance of this class for your ServerContainer descendant. Then you are ready to start created container and you can accept incoming connections. ServerContainer and WebSocketEngine instance you created should be used during whole life of deployed application. All objects created from this point on are related directly to ongoing connection / web socket session app. WebSocketEngine has upgrade method which will validate incoming HTTP request and creates outgoing response. It returns UpgradeInfo, which has status (HANSDHAKE_FAILED, NOT_APPLICABLE, SUCCESS) and can create connection in case status is SUCCESS. HANDSHAKE_FAILED means there were some errors in HTTP header, NOT_APPLICABLE means that passed request is not upgrade request and you might want to pass it to further in the processing chain. For creating a connection, you need to have Writer implementation (very same interface is used on client side). Then the processing is simple – you just read the data from the connection, call connection.getReadHandler().handle(ByteBuffer), data is written through provided Writer implementation. And that’s pretty much it. Sample code for this is not as simple as in client case and there would be left-out things, so lets skip it in this section. InMemory container implements both client and server in the easiest way possible, so if you are still interested, just continue reading. In-memory container This is nothing else than a simple test for both SPIs. It can be used for fast unit/e2e testing if you don’t need anything else than Tyrus runtime and you are fine that each connectToServer method call will create its own “server” container (you cannot connect from two clients to one in-memory server). The best way how to explore that code would be check it out, open in your favourite IDE. You should be also able to see javadocs and maybe start debugging session to really see what is called when and so on. Links to InMemory container implementation: InMemoryClientContainer.java InMemoryContainerProvider.java And I think that was enough for this post. Feel free to ask about whatever you want to know about Tyrus or WebSocket implementation. As almost always, you can find list of relevant links at the very bottom. Links Tyrus 1.3.3 sources Tyrus Servlet 3.1 container Tyrus Grizzly server container Tyrus Grizzly client container Tyrus homepage Tyrus JIRA

This blog post will be little more technical and insightful into Tyrusinternals and won’t be as useful for common users which are just trying to use it for creating their web socket endpoint. I...

Optimized WebSocket broadcast

Broadcast scenario is one of the most common use cases for WebSocket server-side code, so we are going to evaluate usability of current version of WebSocket API for Java to do that and suggest some improvements. Please note that this post is experimental by its nature. You can use Tyrus features mentioned in this article, but anything can change any time, without warning. When speaking about broadcast, let's define what that actually is. When message is broadcasted,  it means that it is sent to all connected clients. Easy right? Common WebSocket sample application is chat (Tyrus is not an exception, see ./samples/chat) which does exactly that - when client sends a message to server endpoint, message gets re-sent to all clients so they can see it. If we ignore authentication and authorisation, we can shrink server-side implementation to following code: @OnMessagepublic void onMessage(Session s, String m) throws IOException { for (Session session : s.getOpenSessions()) { session.getBasicRemote().sendText(m); }} Which works well and provides expected functionality. Underlying code must process the message for every connected client, so the DataFrame which will be sent on the is constructed n-times (where n is number of connected clients). Everything now depends on processing time required for creating single data frame. That operation is not expensive per say, but just the fact it needs to be invoked that many times creates a bottle neck from it. Another important fact is that the WebSocket connection has no state, so once created data frame can be sent to as many clients as you want. So in another words, we don't really need to do create data frame multiple times, especially when we know that the message is the same for all connected clients. WebSocket API does not allow consumers to access messages on data frame level and also does not provide way how to send already constructed data frame. That might come in some next version of the specification... so what can we do now? If you are using Tyrus (1.3 or newer), you can try an optimized version of the same use-case: @OnMessagepublic void onMessage(Session s, String m) { ((TyrusSession) s).broadcast(m);} This way, data frame will be constructed only once which will save server-side resources and additionally clients will receive broadcasted message in shorter period. "broadcast" method returns Map<Session, Future<?>> which can be used for getting the info about which message was already send and which wasn't. Version with callback is not yet available, might be added later (if you'd want to have this feature, please send us a note to users@tyrus.java.net). I don't have any exact measurements to confirm performance gain when using Tyrus broadcast, but seems like it may be significant, especially for higher count of connected clients. (note to JDK8 users: the first scenario can also be improved by using fork/join framework. It was intentionally ignored in this article, since Tyrus need to stick with Java SE 7 for now) If you have any questions, don't hesitate and ask at users@tyrus.java.net. And, as always, list of related links: https://tyrus.java.net https://java.net/jira/browse/TYRUS/ https://github.com/tyrus-project/tyrus

Broadcast scenario is one of the most common use cases for WebSocket server-side code, so we are going to evaluate usability of current version of WebSocket API for Java to do that and suggest some...

Asynchronous connectToServer

Users of JSR-356 – Java API for WebSocket are probably familiar with WebSocketContainer#connectToServer method. This article will be about its usage and improvement which was introduce in recent Tyrus release.WebSocketContainer#connectToServer does what is says, it connects to WebSocketServerEndpoint deployed on some compliant container. It has two or three parameters (depends on which representation of client endpoint are you providing) and returns aSession. Returned Session represents WebSocket connection and you are instantly able to send messages, register MessageHandlers, etc.An issue might appear when you are trying to create responsive user interface and use this method – its execution blocks until Session is created which usually means some container needs to be started, DNS queried, connection created (it’s even more complicated when there is some proxy on the way), etc., so nothing which might be really considered as responsive. Trivial and correct solution is to do this in another thread and monitor the result, but.. why should users do that? :-) Tyrus now provides async* versions of all connectToServer methods, which performs only simple (=fast) check in the same thread and then fires a new one and performs all other tasks there. Return type of these methods is Future<Session>.List of added methods:public Future<Session> asyncConnectToServer(Class<?> annotatedEndpointClass, URI path)public Future<Session> asyncConnectToServer(Class<? extends Endpoint>  endpointClass, ClientEndpointConfig cec, URI path)public Future<Session> asyncConnectToServer(Endpoint endpointInstance, ClientEndpointConfig cec, URI path)public Future<Session> asyncConnectToServer(Object obj, URI path)As you can see, all connectToServer variants have its async* alternative. All these methods do throw DeploymentException, same as synchronous variants, but some of these errors cannot be thrown as a result of the first method call, so you might get it as the cause ofExecutionException thrown when Future<Session>.get() is called.Please let us know if you find these newly added methods useful or if you would like to change something (signature, functionality, …) – you can send us a comment to users@tyrus.java.net or ping me personally.Related links:https://tyrus.java.nethttps://java.net/jira/browse/TYRUS/https://github.com/tyrus-project/tyrus

Users of JSR-356 – Java API for WebSocket are probably familiar with WebSocketContainer#connectToServer method. This article will be about its usage and improvement which was introduce in recent...

Tyrus 1.3

I’m pleased to announce that new version of Tyrus was released today. It contains some interesting features, like asynchronous handling of connectToServer method call, optimised broadcast support and lots of stability and performance improvements. As previously – I will follow with more blog posts about selected features later. Some of them are already described in updated User guide. Complete list of bugfixes and new featuresTYRUS-262: @OnOpen fails for programmatically deployed annotated endpoint.TYRUS-261: Text decoder disables Binary decoder if both are configured for the same server endpoint; endpoint cannot receive binary messages anymore.TYRUS-248: Consolidate Extension representationTYRUS-258: Tyrus always creates HTTP sessionTYRUS-251: DecodeException is not passed to @OnError methodTYRUS-252: encoder for primitive types cannot be overridden.TYRUS-250: Sec-WebSocket-Protocol header cannot be present when there is no negotiated subprotocolTYRUS-249: WebSocketContainer MaxSessionIdleTimeout is not propagated to Session (server side)TYRUS-257: Async timeout value set on WebSocketContainer is not propagated to RemoteEndpoints (Session#getAsyncRemote())TYRUS-253: DecodeException is not passed to @OnError method from session.getAsyncRemote().sendObjectTYRUS-243: WebSocketContainer.connectToServer can block for secondsTYRUS-227: Build failure : AsyncBinaryTestTYRUS-226: Tyrus build error : OnCloseTestTYRUS-247: Make all samples use TestContainer for testsTYRUS-238: Refactor WebSocketEngine (SPI and Impl)TYRUS-157: Submitting tasks to an injected ManagedExecutorService in a ServerEndpoint does not workTYRUS-137: Improve subprotocols/extensions headers parsingTYRUS-133: Some Broadcast(er) API is needed in order to opmtimize chat-like usecasesTYRUS-245: ServerEndpointConfig#getConfiigurator returns Configurator not used when getNegotiatedExtensions has been called.TYRUS-240: clean up duplicated static fields (strings)TYRUS-230: When Session is invalidated, the close reason is not 1006TYRUS-190: Remove TyrusServetServerContainer (merge with TyrusServerContainer)TYRUS-65: Implement common utilities for testingTYRUS-242: Tyrus does not run on JDK8 compact2 profileTYRUS-237: RemoteEndpoint.Async#sendBinary does not throw IllegalArgumentException when data is nullTYRUS-239: Improve WebSocketEngine ByteBuffer handlingTYRUS-232: Refactor grizzly/servlet container – Tyrus-SPITYRUS-235: Fix findbugs errors in tests/servletTYRUS-234: Remove support for older protocol versionTYRUS-229: Session#setMaxIdleTimeout() will kill the session whether or not the session actually timed outTYRUS-225: Invalidation of (Servlet) HttpSession does not invalidate WebSocket SessionTYRUS-153: Static map in TyrusRemotEndpointTYRUS-201: Wrong ServletInputStream#isReady() usage in TyrusHttpUpgradeHandlerTYRUS-224: Refactor Connection#write and ConnectionImpl to use CompletionHandler only (no Future)TYRUS-221: wss:// doesn’t appear to function correctly via a http proxy.TYRUS-146: Support request from client to secured services (“wss”)TYRUS-223: Message can be writen multiple times when running on Servlet container TYRUS-71: ErroCollector not properly used in AnnotatedEndpoint class. Tyrus 1.3 will be integrated in Glassfish trunk soon – you can download nightly build or upgrade to newer Tyrus manually (replace all Tyrus jars).

I’m pleased to announce that new version of Tyrus was released today. It contains some interesting features, like asynchronous handling of connectToServer method call, optimised broadcast support and...

Securing WebSocket applications on Glassfish

Today we are going to cover deploying secured WebSocket applications on Glassfish and access to these services using WebSocket Client API. WebSocket server application setup Our server endpoint might look as simple as this: @ServerEndpoint("/echo")public class EchoEndpoint { @OnMessage  public String echo(String message) {    return message + " (from your server)";  }} Everything else must be configured on container level. We can start with enabling SSL, which will require web.xml to be added to your project. For starters, it might look as following: <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee">  <security-constraint>    <web-resource-collection>      <web-resource-name>Protected resource</web-resource-name>      <url-pattern>/*</url-pattern>      <http-method>GET</http-method>    </web-resource-collection>    <!-- https -->    <user-data-constraint>      <transport-guarantee>CONFIDENTIAL</transport-guarantee>    </user-data-constraint>  </security-constraint></web-app> This is minimal web.xml for this task - web-resource-collection just defines URL pattern and HTTP method(s) we want to put a constraint on and user-data-constraint defines that constraint, which is in our case transport-guarantee. More information about these properties and security settings for web application can be found in Oracle Java EE 7 Tutorial. I have some simple webpage attached as well, so I can test my endpoint right away. You can find it (along with complete project) in Tyrus workspace: [webpage] [whole project]. After deploying this application to Glassfish Application Server, you should be able to hit it using your favorite browser. URL where my application resides is https://localhost:8181/sample-echo-https/ (may be different, depends on other configuration). My browser warns me about untrusted certificate (I use what freshly built Glassfish provides - self signed certificates) and after adding an exception for this site, I can see my webpage and I am able to securely connect to wss://localhost:8181/sample-echo-https/echo. WebSocket client Already mentioned demo application also contains test client, but execution of this is skipped for normal build. Reason for this is that Glassfish uses these self-signed "random" untrusted certificates and you are (in most cases) not able to connect to these services without any additional settings. Creating test WebSocket client is actually quite similar to server side, only difference is that you have to somewhere create client container and invoke connect with some additional info. Java API for WebSocket allows you to use annotated and programmatic way to construct endpoints. Server side shows the annotated case, so let's see how the programmatic approach will look. final WebSocketContainer client = ContainerProvider.getWebSocketContainer();client.connectToServer(new Endpoint() {  @Override  public void onOpen(Session session, EndpointConfig EndpointConfig) {    try {      // register message handler - will just print out the      // received message on standard output.      session.addMessageHandler(new MessageHandler.Whole<String>() {       @Override        public void onMessage(String message) {         System.out.println("### Received: " + message);        }      });      // send a message      session.getBasicRemote().sendText("Do or do not, there is no try.");    } catch (IOException e) {      // do nothing    }  }}, ClientEndpointConfig.Builder.create().build(),   URI.create("wss://localhost:8181/sample-echo-https/echo")); This client should work with some secured endpoint with valid certificated signed by some trusted certificate authority (you can try that with wss://echo.websocket.org). Accessing our Glassfish instance will require some additional settings. You can tell Java which certificated you trust by adding -Djavax.net.ssl.trustStore property (and few others in case you are using linked sample). Complete command line when you are testing your service might need to look somewhat like: mvn clean test -Djavax.net.ssl.trustStore=$AS_MAIN/domains/domain1/config/cacerts.jks\ -Djavax.net.ssl.trustStorePassword=changeit -Dtyrus.test.host=localhost\ -DskipTests=false Where AS_MAIN points to your Glassfish instance. Note: you might need to setup keyStore and trustStore per client instead of per JVM; there is a way how to do it, but it is Tyrus proprietary feature: http://tyrus.java.net/documentation/1.2.1/user-guide.html#d0e1128. And that's it! Now nobody is able to "hear" what you are sending to or receiving from your WebSocket endpoint. There is always room for improvement, so the next step you might want to take is introduce some authentication mechanism (like HTTP Basic or Digest). This topic is more about container configuration so I'm not going to go into details, but there is one thing worth mentioning: to access services which require authorization, you might need to put this additional information to HTTP headers of first (Upgrade) request (there is not (yet) any direct support even for these fundamental mechanisms, user need to register Configurator and add headers in beforeRequest method invocation). I filed related feature request as TYRUS-228; feel free to comment/vote if you need this functionality.

Today we are going to cover deploying secured WebSocket applications on Glassfish and access to these services using WebSocket Client API. WebSocket server application setup Our server endpoint might...

WebSocket via HTTP proxy

As you might know, WebSocket can be used for bi-directional "real-time" communication with multiple clients. What does that mean in proxy environments and how this even works? WebSocket uses HTTP upgrade mechanism specified in HTTP 1.1 and by design requires open (TCP) connection.HTTP CONNECT is there for exactly these usecases. It is usually used for tunneling HTTPS via proxy, but it can be used for WebSocket as well.I will describe complete "proxified" handshake using captured connection of Tyrus Client connecting to public echo service - echo.websocket.org. Please note that we are directly using Tyrus API - not WebSocket specification (JSR-356), because we need to set a proxy.final ClientManager client = ClientManager.createClient();client.getProperties().put( GrizzlyClientSocket.PROXY_URI, "http://my.proxy:8080");final Session session = client.connectToServer(new Endpoint() {  @Override  public void onOpen(Session session, EndpointConfig config) {    session.addMessageHandler(new MessageHandler.Whole<String>() {      @Override      public void onMessage(String message) {        System.out.println("# Message received: " + message);      }    });  }}, ClientEndpointConfig.Builder.create().build(),   URI.create("ws://echo.websocket.org"));session.getBasicRemote().sendText("test message");BTW, Tyrus Client proxy support can be improved, currently it does not support proxy authentication, JDK's ProxySelector and so on. Please vote/comment on TYRUS-204 if you lack some of the mentioned options or anything else related to proxy support.Current modern browsers do support this out of the box, so all you need is to set your HTTP proxy and described handshake will be done automatically. There might be limitation for parallel open connection in browser tab/instance, but I don't have any exact data about this.Also, you might ask whether there is some need to server-side support - simple answer is "no". HTTP containers will see regular connection (from proxy), there is no additional work or overhead on that side.Lets see our dumped communication:client > proxyCONNECT echo.websocket.org:80 HTTP/1.1Host: echo.websocket.orgProxy-Connection: keep-aliveConnection: keep-aliveFirstly, client need to send a request to proxy for new "permanent" connection. As already mentioned, CONNECT method handles this. First argument is a hostname (echo.websocket.org) and standard HTTP version.proxy > clientHTTP/1.0 200 Connection establishedIf you are lucky, your proxy does support CONNECT and allows you to create connection (HTTP 200 is returned).client > proxyGET / HTTP/1.1Connection: UpgradeHost: echo.websocket.orgOrigin: echo.websocket.orgSec-WebSocket-Key : sDD3Wk7PMRCPE9+C0VyOcQ==Sec-WebSocket-Version: 13Upgrade: websocketThis is standard WebSocket handshake request, which will be passed to target HTTP container.proxy > clientHTTP/1.1 101 Web Socket Protocol HandshakeUpgrade: WebSocketConnection: UpgradeSec-WebSocket-Accept: 8TNIHr7bJHqQadjXYvqLql6RFEA=Date: Tue, 16 Jul 2013 15:30:53 GMT...And there is a valid response to our handshake request, connection is established and communication can be started; there is nothing else different than in proxy-less environment. Please note that proxies do have limited resources and your request may be turned down because proxy "CONNECT" pool is empty.Conclusion here is that WebSocket can work via proxies without any limitation, it just introduces different kind of traffic than pure HTTP and might cause some additional requirements related to proxy performance in case you are going to use WebSocket for long-running client connections.

As you might know, WebSocket can be used for bi-directional "real-time" communication with multiple clients. What does that mean inproxy environments and how this even works? WebSocket uses...

WebSocket command line client

Tyrus 1.1 brings new feature - simple command line client, which can be useful in many scenarios. You can use it for simple development testing, sanity testing or for monitoring of your deployed endpoints. How to use: Download latest tyrus-client-cli binary (current version is 1.1): # you can use wget .. or anything else you like:wget http://search.maven.org/remotecontent?filepath=org/glassfish/tyrus/ext/tyrus-client-cli/1.1/tyrus-client-cli-1.1.jar -O ./tyrus-client-cli-1.1.jar Execute downloaded binary java -jar ./tyrus-client-cli-1.1.jar --help that should print out usage information. Tyrus CLI client currently supports sending text messages and pings to one opened endpoint + you can close current session and connect to another one within one run. (If you try to open another connection while having another one already connected, close will be invoked automatically, so you will be still talking only to one endpoint). Example: $ java -jar ./tyrus-client-cli-1.1.jar ws://echo.websocket.org# Connecting to ws://echo.websocket.org...# Connected in session e303ad22-c5af-4bc3-9384-58ce6832ae94session e303...ae94> ping# pong-messagesession e303...ae94> send tyrus-test-message# text-message: tyrus-test-messagesession e303...ae94> close# closed: CloseReason[1000,no reason given]# Session closed note: lines starting with hash '#' symbol are generated from the client runtime, "# text-message: ..." means text message was received, etc. This utility can be improved, please let us know if you have any suggestions about what feature would you like to add. Many thanks to Gerard Davison for contributing main functionality of this module!

Tyrus 1.1 brings new feature - simple command line client, which can be useful in many scenarios. You can use it for simple development testing,sanity testing or for monitoring of your deployed...

Tyrus 1.0-rc1 released

Glassfish HCF is almost here, so is another Tyrus release. This one should be feature complete – that means all features and usecases described in the WebSocket specification (JSR 356) should work. We’ll see how many bugs will be raised after release.. Anyway, new WebSocket API (1.0-rc3) was released in the meantime, so there are some changes which might affect existing applications written using Tyrus/WebSocket API. So let’s start: ServerContainerProvider is gone. ServerEndpointConfig.Configurator#matchesURI is gone Encoder/Decoder.Adapter is gone. And that’s basically it. There are additional changes in the spec document, mostly related to wording and some corner cases, but there is one thing which I want to point out – WebSocket spec 1.o-rc3 introduces path matching algorithm. See the spec itself for detailed description, but short summary would be: we got rid of customizable URI matching and replaced it with “standard” one, which still allows path templates and solves issue with multiple templates matching to same path. Additionally, RI (Tyrus) should not allow to deploy two endpoints with exactly same path templates (in terms of parsed state, so.. “/foo/bar” and “/foo/{bar}” are different, but “/foo/{bar}” and “/foo/{baz}” are the same). Tyrus already implements it, so you can checkout latest Glassfish and try it out or wait for b83. Other changes in Tyrus itself were mainly about getting done spec features and some bugfixing (of course). Latest and more interrestion additions are session timeouts and buffer size implementations. Also we managed to resolve threading issues on linux, so if you have experienced them, please try recent Glassfish and let us know if you still see any issue. I hope that covers all bigger changes, but this post is not supposed to be complete list; if you want to see them all, please check API javadoc and spec document. And as always, you can always ask us! Tyrus (implementation): users@tyrus.java.net ; API: users@websocket-spec.java.net.

Glassfish HCF is almost here, so is another Tyrus release. This one should be feature complete – that means all features and usecases described in the WebSocket specification (JSR 356) should work....

Tyrus 1.0-b13 released

Tyrus 1.0-b13 is out and it brings new WebSocket API 1.0-rc1, which contains some bigger renames and additions, like the last time. Since it is going to affect almost all code written using previous API, I'll again try to summarize changes to make transition as easy as possible.RenamesOriginalNewEndpointConfigurationEndpointConfigServerEndpointConfigurationServerEndpointConfigClientEndpointConfigurationClientEndpointConfigServerEndpointConfiguratorServerEndpointConfig.ConfiguratorClientEndpointConfiguratorClientEndpointConfig.ConfiguratorServerApplicationConfigurationServerApplicationConfigServerEndpointConfigurationBuilderServerEndpointConfig.BuilderClientEndpointConfigurationBuilderClientEndpointConfig.BuilderMessageHandler.BasicMessageHandler.WholeMessageHandler.AsyncMessageHandler.PartialNew FeaturesEncoder and Decoder interface got two new methods - init(EndpointConfig) and destroy(). As you most likely guessed out already, init is called when Encoder/Decoder is initiated and destroy when it is going to be destroyed or no longer used. Lifecycle of these objects changed from singleton to per session. Additionally Encoder.Adapter and Decoder.Adapter were added with empty impl of mentioned methods to ease implementing custom coders which do not rely on newly added methods.ServerContainer and ServerContainerProvider have been introduced, but there is still open discussion about functionality they should provide, so some changes might happen here. ServerContainer allows users to "dynamically" add some endpoints during deployment, but its functionality is limited only to Servlet deployment phase. See javadoc for more information or check out test on Tyrus workspace - tests/servlet/dynamic-deploy or download from maven central - dynamic-deploy sample.WebSocketContainer connectToServer(...) methods which take endpoint instance are back, enjoy ;)EndpointConfig now has getters for sets of Encoder/Decoder classes instead of instances (it relies to scope change mentioned in 3 paragraphs above). It also nicely matches annotated case (see @ServerEndpoint and @ClientEndpoint).ServerEndpointConfig.Configurator (used to be ServerEndpointConfigurator) has one new method getEndpointInstance(Class<T> clazz), which can be overridden and will be used to create new instances of all endpoints. So you can easily influence scoping of created instances. But beware, you won't be able to do anything more granular than one endpoint instance per session. Container provided implementation should support EJB and CDI, check out our CDI sample.I hope that covers all bigger changes, other things are minor modifications mostly, like changing thrown exceptions etc. This short post is not supposed to be complete list of changes, if you want to see them all, please check API is javadoc and spec document: http://java.net/projects/websocket-spec/downloads/directory/Spec%20javadoc%20Drafts/Proposed%20Final%20Draft . And as always, you can always ask us! Tyrus (implementation): users@tyrus.java.net ; API: users@websocket-spec.java.net.

Tyrus 1.0-b13 is out and it brings new WebSocket API 1.0-rc1, which contains some bigger renames and additions, like the last time. Since itis going to affect almost all code written using previous...

Tyrus 1.0-b12 released

This release implements new version of WebSocket API which introduces major renames and even some changes in the way how you can configure advanced behavior. Unfortunately, this will make all related applications written using Tyrus uncompilable and already compiled ones undeployable (when integrated to Glassfish). I'm sure we will receive lots of bugs relates to this change, but all I can do is try to prevent is somehow - for example by writing list of changes which you are reading right now :). Important renames Original name Current name @WebSocketEndpoint @ServerEndpoint @WebSocketClient @ClientEndpoint @WebSocketOpen @OnOpen @WebSocketMessage @OnMessage @WebSocketPathParam @PathParam @WebSocketClose @OnClose @WebSocketError @OnError There were no changes in packaging, so javax.websocket or javax.websocket.server is still valid. Other changes Another set of changes is related to Endpoint configuration. ServerEndpointConfiguration and ClientEndpointConfiguration is still there, but default implementations are gone (package private); users are supposed to use ServerEndpointConfiguraiontBuilder and ClientEndpointConfigurationBuilder in order to create new configuration instance. This change is not yet complete, so prepare for another renaming (Configuration will be Config). Last but not least is separating user implementation from Configuration to Configurator. There are two of them, Server and Client side and they take care of calls like "matchURI", "modifyHandshake", "beforeRequest", "afterResponse". Usually you don't really need to call them, so API/RI providers default implemetation, but you might find these useful in some advanced cases, like implementing your own totally cool and unheard path matching algorithm. This class will also be renamed in next release (to something like ServerEndpointConfig.Configurator), but functionality should stay very similar (if not exactly the same). Additionall, @ServerEndpoint and @ClientEndpoint now do NOT have configuration parameter. Everything from EndpointConfiguration should be configurable as annotation parameters plus you can set Configurator here for some more advanced usecases. Deployment has been also altered. ServerApplicationConfiguration now deploys annotated classes or ServerEndpointConfiguration INSTANCES. Newly introduced method "getEndpointConfigurations" takes set of scanned Endpoint descendants and its up to implementor which of them will be included in returned set. Endpoint descendant needs some more info about the deployment (path, encoders, decoders, ...), so ServerEndpointConfiguration has to be created. Please note that any "loadable" endpoint can be returned (scanned classes may be ignored). Session interface also received some refactorings, "getRemote()" dissapeared and was replaced by "getBasicRemote()" and "getAsyncRemote()". You can guess what can you do with them. On a related note - RemoteEndpoint is no longer usable on its own, it just provides common base for RemoteEndpoint.Basic and RemoteEndpoint.Async. Methods related to sending messages were also renamed, sendString is now sendTest, sendBytes is now sendBinary and these names are used for partial messages as well (only difference is now different parameters). Let's get to the code part: Plain echo endpoint: @ServerEndpoint("/plainEcho")public class PlainEcho {    @OnMessage    public String onMessage(String s) {        return s;    }} ServerEndpointConfigugurator:     @ServerEndpoint(value = "/echo", configurator = MyServerConfigurator.class)    public static class TestEndpoint {        @OnMessage        public String onMessage(String message) {            return message;        }    }    public static class MyServerConfigurator extends ServerEndpointConfigurator {        @Override        public void modifyHandshake(ServerEndpointConfiguration sec, HandshakeRequest request, HandshakeResponse response) {            final List<String> list = request.getHeaders().get(HEADER_NAME);            response.getHeaders().put(HEADER_NAME, list);        }    } ServerApplicationConfiguration programmatic deployment:     public static class MyAppConfig implements ServerApplicationConfiguration {        @Override        public Set<ServerEndpointConfiguration> getEndpointConfigurations(Set<Class<? extends Endpoint>> endpointClasses) {            return new HashSet<ServerEndpointConfiguration>() {{                add(ServerEndpointConfigurationBuilder.create(MyEndpoint.class, "/myEndpoint").build());            }};        }        @Override        public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {            return null;        }    } Session:     @OnOpen    public void onOpen(Session session) throws IOException {        session.getBasicRemote().sendText("onOpen");        session.getBasicRemote().sendBinary(byteBuffer);        final Future<Void> future = session.getAsyncRemote().sendText("myText");    } I'm sure I did not covered all changes (things are still moving forward); best source for info about API is javadoc and spec document: http://java.net/projects/websocket-spec/downloads/directory/Spec%20javadoc%20Drafts/v013 . And as always, you can always ask us! Tyrus (implementation): users@tyrus.java.net ; API: users@websocket-spec.java.net.

This release implements new version of WebSocket API which introduces major renames and even some changes in the way how you can configure advanced behavior. Unfortunately, this will make allrelated...

Tyrus 1.0-b09 released

I've started working on new project - Reference Implementation of JSR 356: Java API for WebSocket - Tyrus and we just released new version. What is Tyrus? Tyrus providers implementation for JSR 356 plus some other (currently minor) improvements. Project itself is still in development phase, so you probably don't want to use it in production environment - especially when specification itself is not yet final - but if you want to be on track with this project, this is the release you want to use. We have worked hard to get implementation to support most of JSR-356 features and hopefully all core functionality. Our implementation passes most of Autobahn testsuite (there are some Servlet 3.1 related issues but also in our implementation, I don't want to blame only Servlet folks ;) ). We should sort that out in next release cycle. How can I try it? Best way would be with fresh Glassfish, which should contain Tyrus 1.0-b09 (it is not available yet, but should be later today; link). Then you can build Echo sample from Tyrus samples directory and start exploring WebSockets and create simple game or other application which can take advantage of bi-directional communication provided by WebSocket protocol. How to run Echo sample: if you really want just quick peek, you can download Tyrus echo sample war file, deploy it and hit deployed application from your browser. But its just "hello world" type app, you most likely want to modify source and play with it. So you'll end up with checking out sources anyway :) svn co https://svn.java.net/svn/tyrus~source-code-repository/tags/tyrus-project-1.0-b09/samples/echocd echomvn clean install Build war file is present in target directory. Please note you might need to disable tests if you are changing functionality (add -Dmaven.test.skip when building sample). If you want more information, check out Public Review draft (spec api version 1.0-b11), and Tyrus home page. As usual, if you find some issues/bugs, feel free to file them on our JIRA or send us a note to users@tyrus.java.net mailing list. Any questions about implementation are also welcomed, so if you are stuck at some point when implementing Tyrus based application, don't hesitated and let us know - we should be able to help you. useful links: latest Glassfish: http://dlc.sun.com.edgesuite.net/glassfish/4.0/nightly/latest-glassfish.zip Tyrus homepage: http://tyrus.java.net/ JSR-356 homepage: http://jcp.org/en/jsr/detail?id=356

I've started working on new project - Reference Implementation of JSR 356: Java API for WebSocket - Tyrus and we just released new version. What is Tyrus? Tyrusproviders implementation for JSR 356 plus...

Jersey - Server and Client side configuration

Originaly this was supposed to be something what are we lacking in our user guide - list of all init params plus at least one sample to each one.. but I wasn't able to finish it yet (and its on my TODO list for at least six months :-| ). But I think just a list with links to javadoc should be useful as well. Please note that this is not complete list and it might be (but I don't guarantee anything) updated in time.Reason why I did this is to sum up all possible properties - it is usable even for me (as a developer) because I can't remember everything :-) And I guess that this list will be sometimes included in Jersey user guide.Server side init params field (declaration) value FeaturesAndPropertiesFEATURE_DISABLE_XML_SECURITY "com.sun.jersey.config.feature.DisableXmlSecurity" FeaturesAndPropertiesFEATURE_FORMATTED "com.sun.jersey.config.feature.Formatted" FeaturesAndPropertiesFEATURE_XMLROOTELEMENT_PROCESSING "com.sun.jersey.config.feature.XmlRootElementProcessing" FeaturesAndPropertiesFEATURE_PRE_1_4_PROVIDER_PRECEDENCE "com.sun.jersey.config.feature.Pre14ProviderPrecedence" JSONMarshallerFORMATTED "com.sun.jersey.api.json.JSONMarshaller.formatted" LoggingFilterFEATURE_LOGGING_DISABLE_ENTITY "com.sun.jersey.config.feature.logging.DisableEntitylogging" ClassNamesResourceConfigPROPERTY_CLASSNAMES "com.sun.jersey.config.property.classnames" ClasspathResourceConfigPROPERTY_CLASSPATH "com.sun.jersey.config.property.classpath" PackagesResourceConfigPROPERTY_PACKAGES "com.sun.jersey.config.property.packages" ResourceConfigFEATURE_NORMALIZE_URI "com.sun.jersey.config.feature.NormalizeURI" ResourceConfigFEATURE_CANONICALIZE_URI_PATH "com.sun.jersey.config.feature.CanonicalizeURIPath" ResourceConfigFEATURE_REDIRECT "com.sun.jersey.config.feature.Redirect" ResourceConfigFEATURE_MATCH_MATRIX_PARAMS "com.sun.jersey.config.feature.IgnoreMatrixParams" ResourceConfigFEATURE_IMPLICIT_VIEWABLES "com.sun.jersey.config.feature.ImplicitViewables" ResourceConfigFEATURE_DISABLE_WADL "com.sun.jersey.config.feature.DisableWADL" ResourceConfigFEATURE_TRACE "com.sun.jersey.config.feature.Trace" ResourceConfigFEATURE_TRACE_PER_REQUEST "com.sun.jersey.config.feature.TracePerRequest" ResourceConfigPROPERTY_MEDIA_TYPE_MAPPINGS "com.sun.jersey.config.property.MediaTypeMappings" ResourceConfigPROPERTY_LANGUAGE_MAPPINGS "com.sun.jersey.config.property.LanguageMappings" ResourceConfigPROPERTY_DEFAULT_RESOURCE_COMPONENT_PROVIDER_FACTORY_CLASS "com.sun.jersey.config.property.DefaultResourceComponentProviderFactoryClass" ResourceConfigPROPERTY_CONTAINER_NOTIFIER "com.sun.jersey.spi.container.ContainerNotifier" ResourceConfigPROPERTY_CONTAINER_REQUEST_FILTERS "com.sun.jersey.spi.container.ContainerRequestFilters" ResourceConfigPROPERTY_CONTAINER_RESPONSE_FILTERS "com.sun.jersey.spi.container.ContainerResponseFilters" ResourceConfigPROPERTY_RESOURCE_FILTER_FACTORIES "com.sun.jersey.spi.container.ResourceFilters" ResourceConfigPROPERTY_WADL_GENERATOR_CONFIG "com.sun.jersey.config.property.WadlGeneratorConfig" ServletContainerGLASSFISH_DEFAULT_ERROR_PAGE_RESPONSE "org.glassfish.web.isDefaultErrorPageEnabled" ServletContainerAPPLICATION_CONFIG_CLASS "javax.ws.rs.Application" ServletContainerRESOURCE_CONFIG_CLASS "com.sun.jersey.config.property.resourceConfigClass" ServletContainerJSP_TEMPLATES_BASE_PATH "com.sun.jersey.config.property.JSPTemplatesBasePath" ServletContainerPROPERTY_WEB_PAGE_CONTENT_REGEX "com.sun.jersey.config.property.WebPageContentRegex" ServletContainerFEATURE_FILTER_FORWARD_ON_404 "com.sun.jersey.config.feature.FilterForwardOn404" ServletContainerPROPERTY_FILTER_CONTEXT_PATH "com.sun.jersey.config.feature.FilterContextPath" WebComponentAPPLICATION_CONFIG_CLASS "javax.ws.rs.Application" WebComponentRESOURCE_CONFIG_CLASS "com.sun.jersey.config.property.resourceConfigClass" WebComponentJSP_TEMPLATES_BASE_PATH "com.sun.jersey.config.property.JSPTemplatesBasePath" Client side init params field (declaration) value ClientConfigPROPERTY_FOLLOW_REDIRECTS "com.sun.jersey.client.property.followRedirects" ClientConfigPROPERTY_READ_TIMEOUT "com.sun.jersey.client.property.readTimeout" ClientConfigPROPERTY_CONNECT_TIMEOUT "com.sun.jersey.client.property.connectTimeout" ClientConfigPROPERTY_CHUNKED_ENCODING_SIZE "com.sun.jersey.client.property.chunkedEncodingSize" ClientConfigPROPERTY_BUFFER_RESPONSE_ENTITY_ON_EXCEPTION "com.sun.jersey.client.property.bufferResponseEntityOnException" ClientConfigPROPERTY_THREADPOOL_SIZE "com.sun.jersey.client.property.threadpoolSize" HTTPSPropertiesPROPERTY_HTTPS_PROPERTIES "com.sun.jersey.client.impl.urlconnection.httpsProperties" URLConnectionClientHandlerPROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND "com.sun.jersey.client.property.httpUrlConnectionSetMethodWorkaround" ApacheHttpClientConfigPROPERTY_INTERACTIVE "com.sun.jersey.impl.client.httpclient.interactive" ApacheHttpClientConfigPROPERTY_HANDLE_COOKIES "com.sun.jersey.impl.client.httpclient.handleCookies" ApacheHttpClientConfigPROPERTY_CREDENTIALS_PROVIDER "com.sun.jersey.impl.client.httpclient.credentialsProvider" ApacheHttpClientConfigPROPERTY_PREEMPTIVE_AUTHENTICATION "com.sun.jersey.impl.client.httpclient.preemptiveAuthentication" ApacheHttpClientConfigPROPERTY_PROXY_URI "com.sun.jersey.impl.client.httpclient.proxyURI" ApacheHttpClientConfigPROPERTY_HTTP_STATE "com.sun.jersey.impl.client.httpclient.httpState" ApacheHttpClient4ConfigPROPERTY_DISABLE_COOKIES "com.sun.jersey.impl.client.httpclient.handleCookies" ApacheHttpClient4ConfigPROPERTY_CREDENTIALS_PROVIDER "com.sun.jersey.impl.client.httpclient.credentialsProvider" ApacheHttpClient4ConfigPROPERTY_PREEMPTIVE_BASIC_AUTHENTICATION "com.sun.jersey.impl.client.httpclient.preemptiveBasicAuthentication" ApacheHttpClient4ConfigPROPERTY_CONNECTION_MANAGER "com.sun.jersey.impl.client.httpclient.connectionManager" ApacheHttpClient4ConfigPROPERTY_HTTP_PARAMS "com.sun.jersey.impl.client.httpclient.httpParams" ApacheHttpClient4ConfigPROPERTY_PROXY_URI "com.sun.jersey.impl.client.httpclient.proxyURI" ApacheHttpClient4ConfigPROPERTY_PROXY_USERNAME "com.sun.jersey.impl.client.httpclient.proxyUsername" ApacheHttpClient4ConfigPROPERTY_PROXY_PASSWORD "com.sun.jersey.impl.client.httpclient.proxyPassword"

Originaly this was supposed to be something what are we lacking in our user guide - list of all init params plus at least one sample to each one.. but I wasn't able to finish it yet (and its on...

Jersey non blocking client

Although Jersey already have support for making asynchronous requests, it is implemented by standard blocking way - every asynchronous request is handled by one thread and that thread is released only after request is completely processed. That is OK for lots of cases, but imagine how that will work when you need to do lots of parallel requests. Of course you can limit (and its really wise thing to do, you do want control your resources) number of threads used for asynchronous requests, but you'll get another maybe not pleasant consequence - obviously processing time will increase. There are few projects which are trying to deal with that problem, commonly named as async http clients. I didn't want to "re-implement a wheel" and I decided I'll use AHC - Async Http Client made by Jeanfrancois Arcand. There is also interesting implementation from Apache - HttpAsyncClient, but it is still in "very early stages of development" and others haven't been in similar or better shape as AHC. How this works? Non-blocking clients allow users to make same asynchronous requests as we can do with standard approach but implementation is different - threads are better utilized, they don't spend most of time in idle state. Simply described - when you make a request (send it over the network), you are waiting for reply from other side. And there comes main advantage of non-blocking approach - it uses these threads for further work, like making other requests or processing responses etc.. Idle time is minimized and your resources (threads) will be far better used. Who should consider using this? Everyone who is making lots of asynchronous requests. I haven't done proper benchmark yet, but some simple dumb tests are showing huge improvement in cases where lots of concurrent asynchronous requests are made in short period. Last but not least - this module is still experimental, so if you don't like something or if you have ideas for improvements/any feedback, feel free to comment this blog post, send mail to users@jersey.java.net or contact me personally. All feedback is greatly appreciated! maven dependency (will be present in java.net maven 2 repo by the end of the day): link: http://download.java.net/maven/2/com/sun/jersey/experimental/jersey-non-blocking-client <dependency> <groupId>com.sun.jersey.experimental</groupId> <artifactId>jersey-non-blocking-client</artifactId> <version>1.9-SNAPSHOT</version></dependency> code snippet: ClientConfig cc = new DefaultNonBlockingClientConfig(); cc.getProperties().put(NonBlockingClientConfig.PROPERTY_THREADPOOL_SIZE, 10); // default value, feel free to change Client c = NonBlockingClient.create(cc); AsyncWebResource awr = c.asyncResource("http://oracle.com"); Future<ClientResponse> responseFuture = awr.get(ClientResponse.class); // or awr.get(new TypeListener<ClientResponse>(ClientResponse.class) { @Override public void onComplete(Future<ClientResponse> f) throws InterruptedException { ... } }); javadoc (temporary location, won't be updated): http://anise.cz/~paja/jersey-non-blocking-client/

Although Jersey already have support for making asynchronous requests, it is implemented by standard blocking way - every asynchronous request ishandled by one thread and that thread is released only...

Sun web app dtds are gone - Error parsing descriptor file WEB-INF/sun-web.xml

UPDATE: Mentioned issue was only a glitch and is fixed now, so original URLs are back online. Anyway that mirror is up too, so someone still could find this useful. As of today, some of our tests began failing and I kind of wondered why (have to do promoted build tomorrow and its not possible to do it without testing) so.. looking at stacktrace: SEVERE: Error parsing descriptor Deployment descriptor file WEB-INF/sun-web.xml in archive [webapp].java.io.IOException: Error parsing descriptor Deployment descriptor file WEB-INF/sun-web.xml in archive [webapp].at com.sun.enterprise.deployment.io.DeploymentDescriptorFile.read(DeploymentDescriptorFile.java:336)at com.sun.enterprise.deployment.archivist.Archivist.readRuntimeDeploymentDescriptor(Archivist.java:558)at com.sun.enterprise.deployment.archivist.ApplicationFactory.openArchive(ApplicationFactory.java:165)at org.glassfish.javaee.core.deployment.JavaEEDeployer.parseModuleMetaData(JavaEEDeployer.java:229)at com.sun.enterprise.web.WebDeployer.parseModuleMetaData(WebDeployer.java:129)at org.glassfish.javaee.core.deployment.JavaEEDeployer.loadMetaData(JavaEEDeployer.java:162)at com.sun.enterprise.v3.server.ApplicationLifecycle.prepare(ApplicationLifecycle.java:455)at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:241)at org.glassfish.embed.GlassFish.deploy(GlassFish.java:422)at com.sun.jersey.samples.helloworld.HelloWorldWebAppTest.setUp(HelloWorldWebAppTest.scala:87)at junit.framework.TestCase.runBare(TestCase.java:132)at junit.framework.TestResult$1.protect(TestResult.java:110)at junit.framework.TestResult.runProtected(TestResult.java:128)at junit.framework.TestResult.run(TestResult.java:113)at junit.framework.TestCase.run(TestCase.java:124)at junit.framework.TestSuite.runTest(TestSuite.java:243)at junit.framework.TestSuite.run(TestSuite.java:238)at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)at org.apache.maven.surefire.Surefire.run(Surefire.java:177)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)Caused by: java.io.FileNotFoundException: http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtdat sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439)at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677)at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1315)at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:1282)at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:283)at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1194)at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1090)at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1003)at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)at com.sun.enterprise.deployment.io.DeploymentDescriptorFile.read(DeploymentDescriptorFile.java:289)... 27 more  it basically tells you everything. Looks like good old http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd is definitely gone.  I haven't noticed any announcement or warning about it and it took a while to find new url but I finally did. Mirror locations for old sun dtds: sun-web-app_2_5-0.dtd -> http://glassfish.java.net/dtds/sun-web-app_2_5-0.dtd sun-web-app_2_4-0.dtd -> http://glassfish.java.net/dtds/sun-web-app_2_4-0.dtd sun-web-app_2_3-0.dtd -> http://glassfish.java.net/dtds/sun-web-app_2_3-0.dtd

UPDATE: Mentioned issue was only a glitch and is fixed now, so original URLs are back online. Anyway that mirror is up too, so someone still could find this useful.As of today, some of our tests began...

Enable/Disable WADL generation in runtime - Jersey 1.7

We've received request about giving more control related to WADL generation, but not that much (no authentication or this kind of features) in runtime. This can be useful for example when you have more than one application deployed and you want to disable WADL generation for all of them - as some security measure. How is it done? You can inject WadlApplicationContext and use its methods - isWadlGenerationEnabled() and setWadlGenerationEnabled(boolean).Use of this is self explanatory, but note that you won't be able to enable WADL for application which disables WADL in web.xml (see ResourceConfig.FEATURE_DISABLE_WADL). Where you can inject this? Almost everywhere, for example to your WebApplicationListener or even into resource class:    @Path("root")    public static class RootResource {        @Get        public String get() {            return "GET";        }        @Path("switch")        @POST        public void switchMethod(@Context WadlApplicationContext wadlApplicationContext) {            wadlApplicationContext.setWadlGenerationEnabled(!wadlApplicationContext.isWadlGenerationEnabled());        }    }As title suggest, this functionality was added in Jersey 1.7.

We've received request about giving more control related to WADL generation, but not that much (no authentication or this kind of features) in runtime. This can be useful for example when you have...

Code coverage using Cobertura

We were requested to investigate and implement code coverage measurement and report generation to our project - Jersey. Nice opportunity to get into new thing and have a motivation to finish (since this was a "must do" type of request..). Alright, let's get into it. At the begging, we had to decide which tool we are going to use - Cobertura [1] won, one of main arguments are nicer reports, active development and price (it's free). There is a nice set of scripts, which can instrument classes/jars, collect & merge generated files and finally create report. This can be used in environment, where you have total control of your classpath and can easily run tests against it. Well, Jersey uses maven, so this is little more difficult, but cobertura does have maven support, so lets try it.. Maven support works perfectly when you have tests in each module and nowhere else, otherwise it is probable you'll run into similar issues as I did.. To be more descriptive: let's say, I have module A (which has some tests) and module B, which depends on A (and also has some tests). By default, code coverage results from B will contain only classes from B, which is not correct, because we want to have complete results. I hit this in Jersey, for example substitute A with "jersey-core" and B with "jersey-tests" and you are there. Solution is not that simple, because you have to somehow force B to use instrumented version of A.. which is not very straightforward using maven.. Solution: You might find or think of few solutions, I like the one described here [2]. Main pom (profile which enables building&local deploying cobertura classified artifacts:  <profile> <id>cobertura</id> <activation> <property> <name>cobertura</name> </property> </activation> <dependencies> <dependency> <groupId>net.sourceforge.cobertura</groupId> <artifactId>cobertura</artifactId> <optional>true</optional> <version>1.9.4.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>cobertura-maven-plugin</artifactId> <executions> <execution> <id>cobertura-instrument</id> <phase>pre-integration-test</phase> <goals> <goal>instrument</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <executions> <execution> <id>cobertura-jar</id> <phase>post-integration-test</phase> <goals> <goal>jar</goal> </goals> <configuration> <classifier>cobertura</classifier> <classesDirectory>${basedir}/target/generated-classes/cobertura</classesDirectory> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> <executions> <execution> <id>cobertura-install</id> <phase>install</phase> <goals> <goal>install</goal> </goals> <configuration> <classifier>cobertura</classifier> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> and additionally, you need to make sure that instrumented artifacts are used during cobertura:cobertura run. What we have here is two profiles, one activated by -Dcobertura and other one by default: <profile> <id>cobertura</id> <activation> <property> <name>cobertura</name> </property> </activation> <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>${project.version}</version> <classifier>cobertura</classifier> </dependency> </dependencies> </profile> <profile> <id>default</id> <activation> <activeByDefault>true</activeByDefault> </activation> <dependencies> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>${project.version}</version> </dependency> </dependencies> </profile> (this is taken from jersey-server module). I encountered some issues with report generation and actually jersey project structure is not simple, so I couldn't use automatic html report generation in pom file.. So we need to collect all generated cobertura.ser files separately, merge it, prepare all sources and generate report. This can be done by following commands: # prepare sourcesmkdir ../sourcesfind . | grep src/main/java$ | while read X ; do cp -r "$X"/\* ../sources/ ; done# compile and run testsmvn clean install -Dmaven.test.skip=true -Dcoberturamvn cobertura:cobertura -Dcobertura -DforkMode=never# collect cobertura.ser files, merge and generate reportfind . | grep cobertura.ser$ | while read X ; do cp "$X" ../cobertura$I.ser ; I=$(($I+1)) ; done;cobertura-merge.sh --datafile ./cobertura_final.ser ../cobertura\*cobertura-report.sh --datafile ./cobertura_filtered.ser --destination ../report --format html ../sources/ Hope it helps somebody who wants to do code coverage for different project. Btw, coverage report for jersey: http://anise.cz/~paja/jersey/report/ [1] http://cobertura.sourceforge.net/[2] http://foobar.lacoctelera.net/post/2008/09/15/uso-del-plugin-cobertura-dentro-un-proyecto-multi-modulo-en

We were requested to investigate and implement code coverage measurement and report generation to our project - Jersey. Nice opportunity to get into new thing and have a motivation to finish (since...

Replacing client used in Jersey Test Framework

There was an interesting question on mailing list - Is it possible to replace default Jersey client in JerseyTest? (JerseyTest is a class from Jersey Test Framework, basically superclass of all "Jersey enabled" tests). Answer is.. not really. It just wasn't made to support this option. Until now :) There was method getClient(), but it couldn't be easily overriden (it was private static) and it actually does more that create Client, so it isn't really method you want to replace. Long story short.. I created overridable ClientFactory which is (surprisingly) responsible for creating new Clients.. Let's say we want to just replace default Jersey Client implementation by Apache: public class MainTest extends JerseyTest { ...     @Override    protected ClientFactory getClientFactory() {        return new ClientFactory() {            @Override            public Client create(ClientConfig clientConfig) {                return ApacheHttpClient.create(clientConfig);            }        };    }} This overrides default client implementation BUT still allows container override this and use its client (this is used for example in InMemoryTestContainer). If you want to have total control and replace even this concept, you can do it by overriding getClient() method: @Override protected Client getClient(TestContainer tc, AppDescriptor ad) { return ApacheHttpClient.create(ad.getClientConfig()); } but I don't recommend this approach, former one should be sufficient in most cases.This functionality is present in 1.6-SNAPSHOT and 1.6-ea03 (and newer Jersey versions).

There was an interesting question on mailing list - Is it possible to replace default Jersey client in JerseyTest? (JerseyTest is a class from Jersey Test Framework, basically superclass of all...

Jersey Client - Making requests with HttpURLConnection hack

HttpURLConnection provided in JDK has serious limitation - you can't do requests with arbitrary chosen method - actually it limit methods to some subsed defined in javadoc, which is NOT extendable in any way.. which might cause some problems. For example you can't do PATCH request because it wasn't in HTTP spec in the time of writing that class. And if you would want to use it for making WebDav client, you are totally lost, it just can't be done.  Well, until now ;) One Jersey user - Markus Karg came with a workaround. Method name can be "injected" to one field in HttpURLConnection via injection and it will be used to create request. We don't want to have this enabled by default, so if you want to use it, you need to set property URLConnectionClientHandler.PROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND to true.         DefaultClientConfig config = new DefaultClientConfig();        config.getProperties().put(URLConnectionClientHandler.PROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND, true);        Client c = Client.create(config);        WebResource r = c.resource(getUri().path("test/entity").build());        ClientResponse cr = r.method("GOTOSLEEP", ClientResponse.class); will produce: Feb 4, 2011 11:25:44 AM com.sun.jersey.api.client.filter.LoggingFilter logINFO: 1 \* Client out-bound request1 > GOTOSLEEP http://localhost:9997/test/test and you can cleary see that method "GOTOSLEEP" was used and HttpURLConnection don't complain about anything. This workaround has some limitation - you can't put an entity to the request. And additionally, it \*probably\* wont work on some containers and maybe in future versions of JDK (containers sometimes have their own implementation of HttpURLConnection).This functionality is available in current Jersey trunk (1.6-SNAPSHOT) and in promoted build 1.6-ea02 (which will be released later today).

HttpURLConnection provided in JDK has serious limitation - you can't do requests with arbitrary chosen method - actually it limit methods to some subsed defined in javadoc, which is NOT extendable in...

Returning XML representation of List from Jersey

One user asked about wrapping element that Jersey uses when serves List<T> recently and I recalled I didn't write a blog post about one change I made in this area so.. here we are..  Jersey supports returning JSR222 (JAXB) annotated classes and even List of them. Let's say we have following class: @XmlRootElementpublic class A {        public String s;        public int i;} and some corresponding method which returns List<A>     @GET    @Path("list")    public List<A> getList() {        ArrayList<A> list = new ArrayList<A>();        return list;     }  when we deploy this and do a GET on /list, we'll see something like <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <as><a><s>first</s><i>1</i></a><a><s>second</s><i>2</i></a></as> which is fine and valid for most cases, but you might need something else. For example, you want to rename <a> to something meaningful, let's say "contract". XmlRootElement annotation has "name" property which is designed for these cases, so lets add it to our class A annotation (@XmlRootElement(name="contract") public class A { ... } ) and make that request again.. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <as><contract><s>first</s><i>1</i></contract><contract><s>second</s><i>2</i></contract></as> Looks better, <a> has changed to <contract> and we might be satisfied.. oh wait, what about <as>? It haven't changed! Firstly, <as> was just plural for <a> and it stayed same when XmlRootElements name property was specified.. oops. This was a bug in Jersey and we couldn't fix it without breaking backwards compatibility, so fix for this is enabled only when FEATURE_XMLROOTELEMENT_PROCESSING is enabled (set to true). Lets do that and see how output changes.. <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <contracts><contract><s>first</s><i>1</i></contract><contract><s>second</s><i>2</i></contract></contracts> Ha, we are almost there. Or.. depends what you want, I guess most of users is satisfied and doesn't need to read further. But there is always someone who wants something "extra".. like specify wrapping element. That is needed for some cases (like B2B communication) and Jersey needs to be able to handle this usecase as well. Unfortunately its not as clean as other solutions. We need to implement our own MessageBodyWriter and for those not familiar with JAX-RS API - it basically allows you to specify how the output will be presented for which mediatype. Your MessageBodyWriter needs to have @javax.ws.rs.ext.Provider  annotation (or be added as provider to ResourceConfig) and implement MessageBodyWriter interface.. I create such class which is sufficient for basic cases, you might want to improve it by creating support for other charsets than UTF-8 or gathering Marshaller from other source that creating new instance.. but at least its a working startpoint.. @Providerpublic class ListAProvider implements MessageBodyWriter<List> {  private String myWrapElemName = "wrapper";  private Marshaller m;  public ListAProvider() throws Exception{    JAXBContext context = JAXBContext.newInstance(A.class);    m = context.createMarshaller();    m.setProperty(Marshaller.JAXB_FRAGMENT, true);  }  @Override  public long getSize(List as, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {    return -1;  }  @Override  public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {    if(mediaType.getSubtype().endsWith("xml") &&          List.class.isAssignableFrom(type) &&          genericType instanceof ParameterizedType) {      if ((((ParameterizedType)genericType).getActualTypeArguments()[0]).equals(A.class)) {        return true;      }    }    return false;  }  @Override  public void writeTo(List list, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {    Charset c = Charset.forName("UTF-8");    String cName = c.name();    entityStream.write(String.format("<?xml version=\\"1.0\\" encoding=\\"%s\\" standalone=\\"yes\\"?>", cName).getBytes(cName));    entityStream.write(String.format("<%s>", myWrapElemName).getBytes(cName));    for (Object o : list)      try {        m.marshal(o, entityStream);      } catch(JAXBException exp) {}    entityStream.write(String.format("</%s>", myWrapElemName).getBytes(cName));  }} when you add this to your Jersey enabled application and make same request as we did earlier, you should get: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <wrapper><contract><s>first</s><i>1</i></contract><contract><s>second</s><i>2</i></contract></wrapper> and we are done for this article, hope somebody will find it useful.

One user asked about wrapping element that Jersey uses when serves List<T> recently and I recalled I didn't write a blog post about one change I made in this area so.. here we are..  Jersey supports...

Jersey Client - Using ContainerListener

I would like to introduce a possibility to monitor connections made within jersey client api. Monitoring in this case means have knowledge about amount of transferred bytes.This functionality is provided (as many others) as a client filter, concretely ConnectionListenerFilter. To create ConnectionListenerFilterinstance, you have to implement OnStartConnectionListener. It might look as follows: class ListenerFactory implements OnStartConnectionListener {     public ContainerListener onStart(ClientRequest cr) {          return new Listener();    }} Looks simple (and it is). This factory creates ContainerListener instance based on ClientRequest. Important note: ClientRequest instance here may be used only for getting values. Any attempt to change anything will produce UnsupportedOperationException.Ok. Now we need ContainerListener implementation. This class is defined as: public abstract class ContainerListener {    public void onSent(long delta, long bytes) {};    public void onReceiveStart(long totalBytes) {};    public void onReceived(long delta, long bytes) {};    public void onFinish() {};} Parameters should be easy to understand, delta is always difference to previous call, bytes is sum of sent/received bytes so far and totalBytes is value from http header (if present, otherwise is set to -1).Every request has a simple "lifecycle":1) Send request2) Receive responseMethod onSent is called during step one only when request has some entity. When request is sent and response has no entity, onFinish() is called and that's it. More interesting scenario is when response contains some entity - onReceiveStart is called after sending a request and onReceived during data receiving. Method onFinish is called after whole entity is read.You will probably have some nice GUI progress bar but I'm going to do only plain text log for now to keep it simple. class Listener extends ContainerListener {     @Override     public void onSent(long delta, long bytes) {         System.out.println("onSent: delta: " + delta + " bytes: " + bytes);     }     @Override     public void onReceiveStart(long totalBytes) {         System.out.println("onReceiveStart: " + totalBytes);     }     @Override     public void onReceived(long delta, long bytes) {         System.out.println("onReceived: delta: " + delta + " bytes: " + bytes);     }     @Override     public void onFinish() {         System.out.println("onFinish");     }} And we're almost done! Last thing to do is register our ListenerFactory as a client filter:     Client c = Client.create();    c.addFilter(new ConnectionListenerFilter(new ListenerFactory())); and actually do a request:     WebResource r = c.resource("http://download.java.net/maven/2/com/sun/jersey/samples/jersey-samples/1.1.0-ea/jersey-samples-1.1.0-ea-project.zip");    r.get(String.class); Output should look like this: onReceiveStart: 615534onReceived: delta: 3677 bytes: 3677onReceived: delta: 2608 bytes: 6285...onReceived: delta: 2608 bytes: 613949onReceived: delta: 1585 bytes: 615534onFinish You can experiment with some requests containing entity (so you will see that onSent method is called during sending). For more information about project Jersey visit http://jersey.dev.java.net

I would like to introduce a possibility to monitor connections made within jersey client api. Monitoring in this case means have knowledge about amount of transferred bytes.This functionality is...

Oracle

Integrated Cloud Applications & Platform Services