{"id":1828,"date":"2014-12-17T16:21:28","date_gmt":"2014-12-17T16:21:28","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1828"},"modified":"2023-06-27T23:16:55","modified_gmt":"2023-06-28T06:16:55","slug":"whats-new-couchbase-java-sdk-12","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/","title":{"rendered":"What&#8217;s new in the Couchbase Java SDK 1.2"},"content":{"rendered":"<p><em style=\"line-height: 23px;font-family: ff-meta-serif-web-pro-1, ff-meta-serif-web-pro-2, Georgia, 'Times New Roman', Times, serif\">[This blog was syndicated from https:\/\/nitschinger.at\/]<\/em><\/p>\n<p>For all users of our Java SDK, we prepared some nice additions for you. This post covers them in detail and shows how you can get more productive<\/p>\n<p>Note that this blog post assumes you are running the 1.2.1 release, because there have been some slight changes between 1.2.0 and 1.2.1 that affect for example the listener support and metrics collection.<\/p>\n<h2>Maven Central Distribution<\/h2>\n<p>From the 1.2.0 release forward, the Java SDK is distributed directly from Maven Central. This means that you don&#8217;t need to include the Couchbase repository anymore. The following maven code is enough to get started (note that the groupId has changed):<\/p>\n<div class=\"geshifilter\">\n<div class=\"xml geshifilter-xml\" style=\"font-family: monospace\"><span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;dependencies<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;dependency<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;groupId<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span>com.couchbase.client<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;artifactId<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span>couchbase-client<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;version<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span>1.2.1<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/div>\n<\/div>\n<p>This will automatically load the latest spymemcached dependency in as well (for 1.2.0 it&#8217;s 2.10.0). Before we dig into what has changed, <a href=\"https:\/\/docs.couchbase.com\/couchbase-sdk-java-1.2\/#release-notes-for-couchbase-client-library-java-120-ga-13-september-2013\">here<\/a>\u00a0are the release notes for a quick reference.<\/p>\n<h2>Listener Support<\/h2>\n<div>Until now, there were two ways to get the result of an asynchronous request. Either by blocking the current thread like so:<\/div>\n<div><\/div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\"><span style=\"color: #666666;font-style: italic\">\/\/ do an async operation (returns immediately)<\/span><br \/>\nOperationFuture<span style=\"color: #339933\">&lt;<\/span>Boolean<span style=\"color: #339933\">&gt;<\/span> setFuture <span style=\"color: #339933\">=<\/span> client.<span style=\"color: #006633\">set<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;key&#8221;<\/span>, <span style=\"color: #0000ff\">&#8220;value&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #666666;font-style: italic\">\/\/ block the current thread<\/span><br \/>\n<a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Aboolean+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">Boolean<\/span><\/a> result <span style=\"color: #339933\">=<\/span> setFuture.<span style=\"color: #006633\">get<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<div><\/div>\n<div>Or to loop on the non-blocking future methods. This is especially helpful if you are dealing with a list of futures.<\/div>\n<div><\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\">List<span style=\"color: #339933\">&lt;<\/span>OperationFuture<span style=\"color: #339933\">&lt;<\/span>Boolean<span style=\"color: #339933\">&gt;&gt;<\/span> futures <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> ArrayList<span style=\"color: #339933\">&lt;<\/span>OperationFuture<span style=\"color: #339933\">&lt;<\/span>Boolean<span style=\"color: #339933\">&gt;&gt;<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #000000;font-weight: bold\">for<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #000066;font-weight: bold\">int<\/span> i <span style=\"color: #339933\">=<\/span> <span style=\"color: #cc66cc\">0<\/span><span style=\"color: #339933\">;<\/span> i <span style=\"color: #339933\">&lt;<\/span> <span style=\"color: #cc66cc\">100<\/span><span style=\"color: #339933\">;<\/span> i<span style=\"color: #339933\">++<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nfutures.<span style=\"color: #006633\">add<\/span><span style=\"color: #009900\">(<\/span>client.<span style=\"color: #006633\">set<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;key-&#8220;<\/span> <span style=\"color: #339933\">+<\/span> i, <span style=\"color: #0000ff\">&#8220;value&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/p>\n<p><span style=\"color: #000000;font-weight: bold\">while<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #339933\">!<\/span>futures.<span style=\"color: #006633\">isEmpty<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nIterator<span style=\"color: #339933\">&lt;<\/span>OperationFuture<span style=\"color: #339933\">&lt;<\/span>Boolean<span style=\"color: #339933\">&gt;&gt;<\/span> iter <span style=\"color: #339933\">=<\/span> futures.<span style=\"color: #006633\">iterator<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #000000;font-weight: bold\">while<\/span> <span style=\"color: #009900\">(<\/span>iter.<span style=\"color: #006633\">hasNext<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nOperationFuture<span style=\"color: #339933\">&lt;<\/span>Boolean<span style=\"color: #339933\">&gt;<\/span> future <span style=\"color: #339933\">=<\/span> iter.<span style=\"color: #006633\">next<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #000000;font-weight: bold\">if<\/span> <span style=\"color: #009900\">(<\/span>future.<span style=\"color: #006633\">isDone<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\niter.<span style=\"color: #006633\">remove<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<\/div>\n<div><\/div>\n<div>Now since 1.2.0, there is a new way to deal with responses &#8211; adding listeners. The idea is to supply a callback to the future which will be executed once the operation is done. A simple example is shown here:<\/div>\n<div><\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\">OperationFuture<span style=\"color: #339933\">&lt;<\/span>Boolean<span style=\"color: #339933\">&gt;<\/span> setFuture <span style=\"color: #339933\">=<\/span> client.<span style=\"color: #006633\">set<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;key&#8221;<\/span>, <span style=\"color: #0000ff\">&#8220;value&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\nsetFuture.<span style=\"color: #006633\">addListener<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #000000;font-weight: bold\">new<\/span> OperationCompletionListener<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n@Override<br \/>\n<span style=\"color: #000000;font-weight: bold\">public<\/span> <span style=\"color: #000066;font-weight: bold\">void<\/span> onComplete<span style=\"color: #009900\">(<\/span>OperationFuture<span style=\"color: #339933\">&lt;?&gt;<\/span> future<span style=\"color: #009900\">)<\/span> <span style=\"color: #000000;font-weight: bold\">throws<\/span> <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Aexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">Exception<\/span><\/a> <span style=\"color: #009900\">{<\/span><br \/>\n<a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">System<\/span><\/a>.<span style=\"color: #006633\">out<\/span>.<span style=\"color: #006633\">println<\/span><span style=\"color: #009900\">(<\/span>future.<span style=\"color: #006633\">get<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<\/div>\n<div><\/div>\n<div>Note that the `.get()` method on the future will not block anymore because the result is already computed. Whatever you put in the callback method will be executed asynchronously on the thread pool. To see how flexible that approach is, let&#8217;s rewrite the example from above waiting until the 100 futures are done.<\/div>\n<div><\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\"><span style=\"color: #000000;font-weight: bold\">final<\/span> CountDownLatch latch <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> CountDownLatch<span style=\"color: #009900\">(<\/span><span style=\"color: #cc66cc\">100<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #000000;font-weight: bold\">for<\/span> <span style=\"color: #009900\">(<\/span><span style=\"color: #000066;font-weight: bold\">int<\/span> i <span style=\"color: #339933\">=<\/span> <span style=\"color: #cc66cc\">0<\/span><span style=\"color: #339933\">;<\/span> i <span style=\"color: #339933\">&lt;<\/span> <span style=\"color: #cc66cc\">100<\/span><span style=\"color: #339933\">;<\/span> i<span style=\"color: #339933\">++<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nOperationFuture<span style=\"color: #339933\">&lt;<\/span>Boolean<span style=\"color: #339933\">&gt;<\/span> future <span style=\"color: #339933\">=<\/span> client.<span style=\"color: #006633\">set<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;key-&#8220;<\/span> <span style=\"color: #339933\">+<\/span> i, <span style=\"color: #0000ff\">&#8220;value&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\nfuture.<span style=\"color: #006633\">addListener<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #000000;font-weight: bold\">new<\/span> OperationCompletionListener<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n@Override<br \/>\n<span style=\"color: #000000;font-weight: bold\">public<\/span> <span style=\"color: #000066;font-weight: bold\">void<\/span> onComplete<span style=\"color: #009900\">(<\/span>OperationFuture<span style=\"color: #339933\">&lt;?&gt;<\/span> future<span style=\"color: #009900\">)<\/span> <span style=\"color: #000000;font-weight: bold\">throws<\/span> <a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Aexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">Exception<\/span><\/a> <span style=\"color: #009900\">{<\/span><br \/>\nlatch.<span style=\"color: #006633\">countDown<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\nlatch.<span style=\"color: #006633\">await<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<\/div>\n<div><\/div>\n<div>Here we are using a <a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/concurrent\/CountDownLatch.html\">CountDownLatch<\/a>\u00a0which waits on the current thread as long as it has been counted down a hundred times. Exactly what we need in our situation, but the code is much easier to read. More importantly, its much more flexible because other things like firing off a new request, querying a web service or calculating a result can be done.<\/div>\n<div><\/div>\n<div>It is also possible to override the default `ExecutorService` implementation with a custom one. This may be needed if the default behavior (Basically a upper-bounded cachedThreadPool) does not suite your needs. Also, you should use this approach if you create a bunch of `CouchbaseClient` instances so you can share the same service across all of them.<\/div>\n<div><\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\"><span style=\"color: #666666;font-style: italic\">\/\/ Create the Builder<\/span><br \/>\nCouchbaseConnectionFactoryBuilder builder <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> CouchbaseConnectionFactoryBuilder<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #666666;font-style: italic\">\/\/ Create a thread pool of 5 fixed threads<\/span><br \/>\nExecutorService service <span style=\"color: #339933\">=<\/span> Executors.<span style=\"color: #006633\">newFixedThreadPool<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc66cc\">5<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #666666;font-style: italic\">\/\/ Set it in the builder<\/span><br \/>\nbuilder.<span style=\"color: #006633\">setListenerExecutorService<\/span><span style=\"color: #009900\">(<\/span>service<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #666666;font-style: italic\">\/\/ Create the instance<\/span><br \/>\nCouchbaseClient client <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> CouchbaseClient<span style=\"color: #009900\">(<\/span>builder.<span style=\"color: #006633\">buildCouchbaseConnection<\/span><span style=\"color: #009900\">(<\/span>&#8230;<span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<\/div>\n<h2>Enhanced Profiling Capabilities<\/h2>\n<div>Getting insight into a running application is always difficult, so we set out to make it easier for you. We incorporated a library called metrics\u00a0that profiles, depending on the configuration level chosen.<\/div>\n<div><\/div>\n<div>Before you can use it, you need to add this optional dependency:<\/div>\n<div><\/div>\n<div class=\"geshifilter\">\n<div class=\"xml geshifilter-xml\" style=\"font-family: monospace\"><span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;dependency<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;groupId<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span>com.codahale.metrics<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;artifactId<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span>metrics-core<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&lt;version<span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/span>3.0.1<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><br \/>\n<span style=\"color: #009900\"><span style=\"color: #000000;font-weight: bold\">&gt;<\/span><\/span><\/div>\n<\/div>\n<div><\/div>\n<div>On the builder, there is a method that allows you to activate the the profiler:<\/div>\n<div><\/div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\">CouchbaseConnectionFactoryBuilder builder <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> CouchbaseConnectionFactoryBuilder<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #666666;font-style: italic\">\/\/ enable metric collection<\/span><br \/>\nbuilder.<span style=\"color: #006633\">setEnableMetrics<\/span><span style=\"color: #009900\">(<\/span>MetricType.<span style=\"color: #006633\">PERFORMANCE<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<div><\/div>\n<div>If you look at the `MetricType` enumeration you can see that there are three types of values you can choose from: OFF (which keeps metric collection off), PERFORMANCE (which only collects performance-relevant metrics) and DEBUG (which collects all kinds of metrics, including the performance ones). While the metrics library is quite efficient, keep in mind that metric collection takes some resources away from your application.<\/div>\n<div><\/div>\n<div>By default, the metric information will be printed out on the console every 30 seconds. You can run the following test code from your IDE and see how it looks:<\/div>\n<div><\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\">CouchbaseConnectionFactoryBuilder builder <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> CouchbaseConnectionFactoryBuilder<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\nbuilder.<span style=\"color: #006633\">setEnableMetrics<\/span><span style=\"color: #009900\">(<\/span>MetricType.<span style=\"color: #006633\">PERFORMANCE<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p>CouchbaseConnectionFactory cf <span style=\"color: #339933\">=<\/span><br \/>\nbuilder.<span style=\"color: #006633\">buildCouchbaseConnection<\/span><span style=\"color: #009900\">(<\/span><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Aarrays+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">Arrays<\/span><\/a>.<span style=\"color: #006633\">asList<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #000000;font-weight: bold\">new<\/span> URI<span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;https:\/\/127.0.0.1:8091\/pools&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">)<\/span>, <span style=\"color: #0000ff\">&#8220;default&#8221;<\/span>, <span style=\"color: #0000ff\">&#8220;&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\nCouchbaseClient client <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> CouchbaseClient<span style=\"color: #009900\">(<\/span>cf<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p><span style=\"color: #000000;font-weight: bold\">while<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #000066;font-weight: bold\">true<\/span><span style=\"color: #009900\">)<\/span> <span style=\"color: #009900\">{<\/span><br \/>\nclient.<span style=\"color: #006633\">set<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;foo&#8221;<\/span>, <span style=\"color: #0000ff\">&#8220;bar&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Athread+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">Thread<\/span><\/a>.<span style=\"color: #006633\">sleep<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #cc66cc\">100<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<div><\/div>\n<\/div>\n<div>Now wait 30 seconds and you&#8217;ll see output like this in the console:<\/div>\n<div><\/div>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">10\/8\/13 12:04:14 PM ============================================================<\/p>\n<p>&#8212; Histograms &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p>[MEM] Average Bytes read from OS per read<\/p>\n<p>count = 893<\/p>\n<p>min = 24<\/p>\n<p>max = 24<\/p>\n<p>mean = 24.00<\/p>\n<p>stddev = 0.00<\/p>\n<p>median = 24.00<\/p>\n<p>75% &lt;= 24.00<\/p>\n<p>95% &lt;= 24.00<\/p>\n<p>98% &lt;= 24.00<\/p>\n<p>99% &lt;= 24.00<\/p>\n<p>99.9% &lt;= 24.00<\/p>\n<p>[MEM] Average Bytes written to OS per write<\/p>\n<p>count = 893<\/p>\n<p>min = 38<\/p>\n<p>max = 38<\/p>\n<p>mean = 38.00<\/p>\n<p>stddev = 0.00<\/p>\n<p>median = 38.00<\/p>\n<p>75% &lt;= 38.00<\/p>\n<p>95% &lt;= 38.00<\/p>\n<p>98% &lt;= 38.00<\/p>\n<p>99% &lt;= 38.00<\/p>\n<p>99.9% &lt;= 38.00<\/p>\n<p>[MEM] Average Time on wire for operations (\u00c2\u00b5s)<\/p>\n<p>count = 893<\/p>\n<p>min = 179<\/p>\n<p>max = 1730<\/p>\n<p>mean = 263.80<\/p>\n<p>stddev = 75.43<\/p>\n<p>median = 251.00<\/p>\n<p>75% &lt;= 280.00<\/p>\n<p>95% &lt;= 351.90<\/p>\n<p>98% &lt;= 425.36<\/p>\n<p>99% &lt;= 559.70<\/p>\n<p>99.9% &lt;= 1730.00<\/p>\n<p>&#8212; Meters &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>[MEM] Request Rate: All<\/p>\n<p>count = 893<\/p>\n<p>mean rate = 9.92 events\/second<\/p>\n<p>1-minute rate = 9.85 events\/second<\/p>\n<p>5-minute rate = 9.68 events\/second<\/p>\n<p>15-minute rate = 9.63 events\/second<\/p>\n<p>[MEM] Response Rate: All (Failure + Success + Retry)<\/p>\n<p>count = 893<\/p>\n<p>mean rate = 9.92 events\/second<\/p>\n<p>1-minute rate = 9.85 events\/second<\/p>\n<p>5-minute rate = 9.68 events\/second<\/p>\n<p>15-minute rate = 9.63 events\/second<\/p><\/div>\n<\/div>\n<div><\/div>\n<div>I won&#8217;t go into detail of all these metrics in this blog post, please refer to the documentation for a more complete picture. One more thing I want to show you is that the metrics library is also able to expose these metrics through JMX. All you need to do is set a system property that changes the output mode: `net.spy.metrics.reporter.type=jmx`. Other possible settings are `csv` and slf4j`. If you choose a logger that prints out information at a given interval you can change it by setting `net.spy.metrics.reporter.interval` to anything else than 30.<\/div>\n<div><\/div>\n<div>So if you put the line `System.setProperty(&#8220;net.spy.metrics.reporter.type&#8221;, &#8220;jmx&#8221;);` before the code shown above, you can open (for example) jConsole and switch to the MBeans tab of the application. You&#8217;ll see a `metrics` subsection exposed that contains the same metrics as they would show up in the logs.<\/div>\n<div><\/div>\n<h2>CAS with Expiration<\/h2>\n<div>Before 1.2.0, it was not possible in one command to do a `cas` update and set a new expiration at the same time. You had to do a second `touch` operation which was not efficient nor atomic. Now, the API exposes a new `cas()` method that allows you to pass in the expiration time at the same time. It is easy to use:<\/div>\n<div><\/div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\">client.<span style=\"color: #006633\">cas<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;key&#8221;<\/span>, cas, newExpiration, value<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<div><\/div>\n<div>The asynchronous variations have been exposed since 1.2.1 as well.<\/div>\n<div><\/div>\n<h2>Initializing through Properties<\/h2>\n<div>One thing that comes in handy if your cluster ip addresses change often is that you can now initialize a `CouchbaseClient` object based on system properties. Here is an example:<\/div>\n<div><\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"java geshifilter-java\" style=\"font-family: monospace\"><a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">System<\/span><\/a>.<span style=\"color: #006633\">setProperty<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;cbclient.nodes&#8221;<\/span>, <span style=\"color: #0000ff\">&#8220;https:\/\/127.0.0.1:8091\/pools&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">System<\/span><\/a>.<span style=\"color: #006633\">setProperty<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;cbclient.bucket&#8221;<\/span>, <span style=\"color: #0000ff\">&#8220;default&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<a href=\"https:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky\"><span style=\"color: #003399\">System<\/span><\/a>.<span style=\"color: #006633\">setProperty<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #0000ff\">&#8220;cbclient.password&#8221;<\/span>, <span style=\"color: #0000ff\">&#8220;&#8221;<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/p>\n<p>CouchbaseConnectionFactoryBuilder builder <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> CouchbaseConnectionFactoryBuilder<span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\nCouchbaseConnectionFactory cf <span style=\"color: #339933\">=<\/span> builder.<span style=\"color: #006633\">buildCouchbaseConnection<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\nCouchbaseClient client <span style=\"color: #339933\">=<\/span> <span style=\"color: #000000;font-weight: bold\">new<\/span> CouchbaseClient<span style=\"color: #009900\">(<\/span>cf<span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><\/div>\n<\/div>\n<\/div>\n<div><\/div>\n<div>Of course you can set these properties in your application container or during startup, so it&#8217;s very flexible and not tied into your code directly. Note that if you forget to set one of these properties, the code will warn you like this:<\/div>\n<div><\/div>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">Exception in thread &#8220;main&#8221; java.lang.IllegalArgumentException: System property cbclient.nodes not set or empty<br \/>\nat com.couchbase.client.CouchbaseConnectionFactory.(CouchbaseConnectionFactory.java:160)<br \/>\nat com.couchbase.client.CouchbaseConnectionFactoryBuilder$2.(CouchbaseConnectionFactoryBuilder.java:318)<br \/>\nat com.couchbase.client.CouchbaseConnectionFactoryBuilder.buildCouchbaseConnection(CouchbaseConnectionFactoryBuilder.java:318)<br \/>\nat Main.main(Main.java:33)<br \/>\nat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br \/>\nat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)<br \/>\nat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)<br \/>\nat java.lang.reflect.Method.invoke(Method.java:601)<br \/>\nat com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)<\/div>\n<\/div>\n<div><\/div>\n<h2>Other Changes<\/h2>\n<div>In addition to the enhancements shown above, the release includes &#8211; as always &#8211; numerous smaller bugfixes. The default poll interval for `ReplicateTo` and `PersistTo` has been lowered to `10ms` to account for performance changes that went into the Couchbase Sever 2.2 release. Also, the client now uses the `CRAM-MD5` authentication mechanism automatically if the server supports it (since 2.2 as well).<\/div>\n<div><\/div>\n<div>These awesome new features should be enough reason to upgrade right now! If anything pops up that doesn&#8217;t work as expected, please ask customer support or open a ticket <a href=\"https:\/\/www.couchbase.com\/issues\/browse\/JCBC\/\">here<\/a>.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>[This blog was syndicated from https:\/\/nitschinger.at\/] For all users of our Java SDK, we prepared some nice additions for you. This post covers them in detail and shows how you can get more productive Note that this blog post assumes [&hellip;]<\/p>\n","protected":false},"author":19,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[8987],"class_list":["post-1828","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>What&#039;s new in the Couchbase Java SDK 1.2 - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"What&#039;s new in the Couchbase Java SDK 1.2\" \/>\n<meta property=\"og:description\" content=\"[This blog was syndicated from https:\/\/nitschinger.at\/] For all users of our Java SDK, we prepared some nice additions for you. This post covers them in detail and shows how you can get more productive Note that this blog post assumes [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-17T16:21:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-06-28T06:16:55+00:00\" \/>\n<meta name=\"author\" content=\"Michael Nitschinger\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@daschl\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michael Nitschinger\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/\"},\"author\":{\"name\":\"Michael Nitschinger\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e5d4d332756da6f361dd88c1576de61d\"},\"headline\":\"What&#8217;s new in the Couchbase Java SDK 1.2\",\"datePublished\":\"2014-12-17T16:21:28+00:00\",\"dateModified\":\"2023-06-28T06:16:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/\"},\"wordCount\":1469,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/\",\"name\":\"What's new in the Couchbase Java SDK 1.2 - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-17T16:21:28+00:00\",\"dateModified\":\"2023-06-28T06:16:55+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"What&#8217;s new in the Couchbase Java SDK 1.2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e5d4d332756da6f361dd88c1576de61d\",\"name\":\"Michael Nitschinger\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/95e178617974d46e3b02dd1754a3f60b\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g\",\"caption\":\"Michael Nitschinger\"},\"description\":\"Michael Nitschinger works as a Principal Software Engineer at Couchbase. He is the architect and maintainer of the Couchbase Java SDK, one of the first completely reactive database drivers on the JVM. He also authored and maintains the Couchbase Spark Connector. Michael is active in the open source community, a contributor to various other projects like RxJava and Netty.\",\"sameAs\":[\"https:\/\/nitschinger.at\",\"https:\/\/x.com\/daschl\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/michael-nitschinger\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"What's new in the Couchbase Java SDK 1.2 - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/","og_locale":"en_US","og_type":"article","og_title":"What's new in the Couchbase Java SDK 1.2","og_description":"[This blog was syndicated from https:\/\/nitschinger.at\/] For all users of our Java SDK, we prepared some nice additions for you. This post covers them in detail and shows how you can get more productive Note that this blog post assumes [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-17T16:21:28+00:00","article_modified_time":"2023-06-28T06:16:55+00:00","author":"Michael Nitschinger","twitter_card":"summary_large_image","twitter_creator":"@daschl","twitter_misc":{"Written by":"Michael Nitschinger","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/"},"author":{"name":"Michael Nitschinger","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e5d4d332756da6f361dd88c1576de61d"},"headline":"What&#8217;s new in the Couchbase Java SDK 1.2","datePublished":"2014-12-17T16:21:28+00:00","dateModified":"2023-06-28T06:16:55+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/"},"wordCount":1469,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/","url":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/","name":"What's new in the Couchbase Java SDK 1.2 - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-17T16:21:28+00:00","dateModified":"2023-06-28T06:16:55+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/whats-new-couchbase-java-sdk-12\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"What&#8217;s new in the Couchbase Java SDK 1.2"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e5d4d332756da6f361dd88c1576de61d","name":"Michael Nitschinger","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/95e178617974d46e3b02dd1754a3f60b","url":"https:\/\/secure.gravatar.com\/avatar\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g","caption":"Michael Nitschinger"},"description":"Michael Nitschinger works as a Principal Software Engineer at Couchbase. He is the architect and maintainer of the Couchbase Java SDK, one of the first completely reactive database drivers on the JVM. He also authored and maintains the Couchbase Spark Connector. Michael is active in the open source community, a contributor to various other projects like RxJava and Netty.","sameAs":["https:\/\/nitschinger.at","https:\/\/x.com\/daschl"],"url":"https:\/\/www.couchbase.com\/blog\/author\/michael-nitschinger\/"}]}},"authors":[{"term_id":8987,"user_id":19,"is_guest":0,"slug":"michael-nitschinger","display_name":"Michael Nitschinger","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/dad99b5e02a74ca4bec14352e9da710160647a97290814b669babb3aac0ea675?s=96&d=mm&r=g","author_category":"","last_name":"Nitschinger, Principal Software Engineer, Couchbase","first_name":"Michael","job_title":"","user_url":"https:\/\/nitschinger.at","description":"Michael Nitschinger works as a Principal Software Engineer at Couchbase. He is the architect and maintainer of the Couchbase Java SDK, one of the first completely reactive database drivers on the JVM. He also authored and maintains the Couchbase Spark Connector. Michael is active in the open source community, a contributor to various other projects like RxJava and Netty."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/19"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=1828"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1828\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=1828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=1828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=1828"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}