[Valid RSS] This is a valid RSS feed.


This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.


  1. <?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
  2. xmlns:content=""
  3. xmlns:wfw=""
  4. xmlns:dc=""
  5. xmlns:atom=""
  6. xmlns:sy=""
  7. xmlns:slash=""
  8. >
  10. <channel>
  11. <title>[email protected]</title>
  12. <atom:link href="" rel="self" type="application/rss+xml" />
  13. <link></link>
  14. <description></description>
  15. <lastBuildDate>Mon, 12 Jun 2017 15:05:56 +0000</lastBuildDate>
  16. <language>de-DE</language>
  17. <sy:updatePeriod>hourly</sy:updatePeriod>
  18. <sy:updateFrequency>1</sy:updateFrequency>
  19. <generator></generator>
  20. <item>
  21. <title>Quick-n-Dirty: Hotfix for DateTimeHelper</title>
  22. <link></link>
  23. <comments></comments>
  24. <pubDate>Mon, 12 Jun 2017 15:04:40 +0000</pubDate>
  25. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  26. <category><![CDATA[Java]]></category>
  27. <category><![CDATA[JSF]]></category>
  28. <category><![CDATA[XPages]]></category>
  29. <category><![CDATA[9.0]]></category>
  30. <category><![CDATA[Bug]]></category>
  31. <category><![CDATA[Domino]]></category>
  33. <guid isPermaLink="false"></guid>
  34. <description><![CDATA[This weekend I stumbled over a bug of the DateTimeHelper: If the value of the field is empty, no actions and/or action listeners connected with a managed bean will be executed anymore. Here is an example of a small XPage &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  35. <content:encoded><![CDATA[<p>This weekend I stumbled over a bug of the <em>DateTimeHelper</em>: If the value of the field is empty, no actions and/or action listeners connected with a managed bean will be executed anymore.</p>
  36. <p>Here is an example of a small XPage to illustrate the problem:</p>
  37. <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  38. &lt;xp:view xmlns:xp=""&gt;
  39.    &lt;xp:label
  40.        value="#{javascript:java.lang.System.currentTimeMillis()}" id="labelNow" /&gt;
  42.     &lt;xp:inputText id="inputTextDT" value="#{myBean.valueDT}"&gt;
  43.         &lt;xp:this.converter&gt;
  44.             &lt;xp:convertDateTime type="date" /&gt;
  45.         &lt;/xp:this.converter&gt;
  46.         &lt;xp:dateTimeHelper /&gt;
  47.     &lt;/xp:inputText&gt;
  49.    &lt;xp:button id="button" value="OK"&gt;
  50.        &lt;xp:eventHandler
  51.            event="onclick"
  52.            submit="true"
  53.            refreshMode="partial"
  54.            refreshId="labelNow"
  55.            actionListener="#{myBean.action}" /&gt;
  56.     &lt;/xp:button&gt;
  58. &lt;/xp:view&gt;</code></pre>
  59. <p>It does not matter if you set the <em>disableValidators</em> property for the text field to <em>true</em>, even an <em>immediate=true</em> won&#8217;t help here. The reason for the problem is that the renderer of the <em>dateTimeHelper </em>always uses the attached converter and fails with a null pointer exception if the value is empty (this infringes the JSF specification, but IBM has implemented it this way).</p>
  60. <p>The workaround for this problem is to overwrite the existing renderer class and handle the NPE by yourself:</p>
  61. <pre><code>package ch.hasselba.xpages.renderer;
  63. import javax.faces.component.UIComponent;
  64. import javax.faces.context.FacesContext;
  65. import javax.faces.convert.ConverterException;
  66. public class DateTimeHelperRenderer
  67.    extends{
  69.     public Object getConvertedValue(FacesContext fc, UIComponent uiComponent, Object obj)
  70.        throws ConverterException  {
  72.          Object result = super.getConvertedValue(fc, uiComponent, obj);
  74.          if( result == null )
  75.            return new Object();
  77.          return result;
  78.    }
  79. }</code></pre>
  80. <p>The renderer must now be registered in <em>faces-config.xml</em>:</p>
  81. <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  82. &lt;faces-config&gt;
  83.  &lt;render-kit&gt;
  84.    &lt;renderer&gt;
  85.      &lt;component-family&gt;javax.faces.Input&lt;/component-family&gt;
  86.      &lt;renderer-type&gt;;/renderer-type&gt;
  87.      &lt;renderer-class&gt;ch.hasselba.xpages.renderer.DateTimeHelperRenderer&lt;/renderer-class&gt;
  88.    &lt;/renderer&gt;
  89.  &lt;/render-kit&gt;
  90. &lt;/faces-config&gt;
  91. </code></pre>
  92. <p>Now the problem is solved, the managed bean&#8217;s action get executed even if the value is empty.</p>
  93. ]]></content:encoded>
  94. <wfw:commentRss>;p=2429</wfw:commentRss>
  95. <slash:comments>1</slash:comments>
  96. </item>
  97. <item>
  98. <title>High Performance REST Applications (4) – Looking into OSGi</title>
  99. <link></link>
  100. <comments></comments>
  101. <pubDate>Thu, 04 May 2017 09:41:43 +0000</pubDate>
  102. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  103. <category><![CDATA[Apache Wink]]></category>
  104. <category><![CDATA[Java]]></category>
  105. <category><![CDATA[JEE]]></category>
  106. <category><![CDATA[OSGi]]></category>
  107. <category><![CDATA[REST]]></category>
  108. <category><![CDATA[Server]]></category>
  109. <category><![CDATA[Web]]></category>
  110. <category><![CDATA[Domino]]></category>
  112. <guid isPermaLink="false"></guid>
  113. <description><![CDATA[Before going any deeper into the the servlet project, let&#8217;s have a look at the imported projects and talk about some OSGi basics. First you will notice that for every cloned repository three Eclipse projects have been imported: A plugin &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  114. <content:encoded><![CDATA[<p>Before going any deeper into the the servlet project, let&#8217;s have a look at the imported projects and talk about some OSGi basics.</p>
  115. <p>First you will notice that for every cloned repository three Eclipse projects have been imported:</p>
  116. <ol>
  117. <li>A plugin project</li>
  118. <li>A feature project</li>
  119. <li>An updatesite project</li>
  120. </ol>
  121. <p>The plugin project contains the code and all the relevant resources of the servlet. It defines extension points provided or describes which extension points are used by the plugin.<br />
  122. A feature project is basically a list of plugins and other features which can be understood as a logical separate unit. And an updatesite contains all features you need.</p>
  123. <p>Using an UpdateSite is the preferred way to deploy plugins to Domino. It has a &#8222;<em>Build All</em>&#8222;-Button which builds all plugins from all features in your updatesite project, and creates the JARs to import into an UpdateSite in Domino.</p>
  124. <div id="attachment_2417" style="width: 486px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2417" src="" alt="" width="476" height="293" srcset=" 476w, 300w" sizes="(max-width: 476px) 100vw, 476px" /></a><p class="wp-caption-text">Update Site &#8222;Build All&#8220;-Button</p></div>
  125. <p>A plugin is mainly described by two files: the <em>MANIFEST.MF</em> (stored in the <em>/META-INF</em> folder) and a <em>plugin.xml</em> in the root.</p>
  126. <div id="attachment_2418" style="width: 415px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2418" src="" alt="" width="405" height="182" srcset=" 405w, 300w" sizes="(max-width: 405px) 100vw, 405px" /></a><p class="wp-caption-text">plugin.xml &amp; MANIFEST.MF</p></div>
  127. <p>The <em>MANIFEST.MF</em> contains meta informations about the Plugin, like the name, imports and exports, other required bundles, the Activator class, the Execution environment and many more.</p>
  128. <p>For example the <em>Domino REST servlet plugin</em> requires the <em>concurrent plugin</em>:</p>
  129. <div id="attachment_2419" style="width: 494px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2419" src="" alt="" width="484" height="375" srcset=" 484w, 300w" sizes="(max-width: 484px) 100vw, 484px" /></a><p class="wp-caption-text">Required Bundles: &#8222;ch.hasselba.concurrent.plugin&#8220;</p></div>
  130. <p>If the bundle is loaded, but the requirements are not fullyfied, the bundle won&#8217;t start.</p>
  131. <p>The <em>plugin.xml</em> is optional for OSGI bundles, but we need this file, because it describes the extension point used by our plugin:</p>
  132. <div id="attachment_2420" style="width: 425px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2420" src="" alt="" width="415" height="235" srcset=" 415w, 300w" sizes="(max-width: 415px) 100vw, 415px" /></a><p class="wp-caption-text">plugin.xml &#8211; Extension Point</p></div>
  133. <p>Our servlet plugin uses the <em></em> extension point to run a JEE application. The parameter <em>contextRoot</em> is the path our servlet listens (which means it will be reachable at <em></em>), and the <em>contentLocation</em> parameter is the path to the static files of the plugin and our <em>web.xml</em>.</p>
  134. <div id="attachment_2421" style="width: 411px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2421" src="" alt="" width="401" height="237" srcset=" 401w, 300w" sizes="(max-width: 401px) 100vw, 401px" /></a><p class="wp-caption-text">WebContent folder</p></div>
  135. <p>An Activator class is the class executed when a bundle is started or stopped (or the other possibilities a <a href="" target="_blank" rel="noopener noreferrer">lifecyle of a bundle</a> can have). It is also a good idea to store the <em>BundleContext</em> in the Activator to communicate with the OSGi environment.</p>
  136. <p>Last but not least, there is a <em></em> file: This file is for Eclipse and contains all relevant information to build the bundle. This means that if you add a JAR file the plugin requires, you have to add the JAR to both &#8211; the <em>MANIFEST.MF</em> and the <em> </em>(if the classes of the JAR file are used in the project).</p>
  137. <p>In the Domino REST Servlet project, the <em>spymemcached.jar</em> is used, that&#8217;s why it is added to the build path and the manifest:</p>
  138. <div id="attachment_2423" style="width: 606px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2423" src="" alt="" width="596" height="227" srcset=" 596w, 300w" sizes="(max-width: 596px) 100vw, 596px" /></a><p class="wp-caption-text"> &#8211; spymemcached JAR</p></div>
  139. <div id="attachment_2422" style="width: 525px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2422" src="" alt="" width="515" height="143" srcset=" 515w, 300w" sizes="(max-width: 515px) 100vw, 515px" /></a><p class="wp-caption-text">MANTIFEST.MF &#8211; spymemcached JAR</p></div>
  140. <p>You have to keep this in your mind, because if you write some code, it is not enough just to add the required JAR to the build path, it also has to be exported in your bundle / plugin.</p>
  141. <p>In the next post, let&#8217;s have a look into <em>web.xml</em>, and then go into the real &#8222;<em>High Performance</em>&#8220; solution.</p>
  142. ]]></content:encoded>
  143. <wfw:commentRss>;p=2413</wfw:commentRss>
  144. <slash:comments>2</slash:comments>
  145. </item>
  146. <item>
  147. <title>High Performance REST Applications (3) – Importing the Starter Project</title>
  148. <link></link>
  149. <comments></comments>
  150. <pubDate>Mon, 24 Apr 2017 09:03:24 +0000</pubDate>
  151. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  152. <category><![CDATA[Java]]></category>
  153. <category><![CDATA[JEE]]></category>
  154. <category><![CDATA[OSGi]]></category>
  155. <category><![CDATA[Performance]]></category>
  156. <category><![CDATA[REST]]></category>
  157. <category><![CDATA[Server]]></category>
  158. <category><![CDATA[Web]]></category>
  159. <category><![CDATA[Domino]]></category>
  161. <guid isPermaLink="false"></guid>
  162. <description><![CDATA[Now you can import the projects required from Git. First, go to &#8222;File &#62; Import&#8230;&#8220; Then select &#8222;Projects from Git&#8220; and &#8222;Clone URI&#8220; to clone an existing repository: To get the URI, you have to open and select the &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  163. <content:encoded><![CDATA[<p>Now you can import the projects required from Git.</p>
  164. <p>First, go to &#8222;<em>File &gt; Import&#8230;</em>&#8220;</p>
  165. <div id="attachment_2398" style="width: 359px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2398" src="" alt="" width="349" height="566" srcset=" 349w, 185w" sizes="(max-width: 349px) 100vw, 349px" /></a><p class="wp-caption-text">Import Project</p></div>
  166. <p>Then select &#8222;<em>Projects from Git&#8220;</em></p>
  167. <div id="attachment_2399" style="width: 535px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2399" src="" alt="" width="525" height="551" srcset=" 525w, 286w" sizes="(max-width: 525px) 100vw, 525px" /></a><p class="wp-caption-text">Projects from Git</p></div>
  168. <p>and &#8222;<em>Clone URI</em>&#8220; to clone an existing repository:</p>
  169. <div id="attachment_2400" style="width: 539px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2400" src="" alt="" width="529" height="556" srcset=" 529w, 285w" sizes="(max-width: 529px) 100vw, 529px" /></a><p class="wp-caption-text">Clone existing respository</p></div>
  170. <p>To get the URI, you have to open <a href="" target="_blank" rel="noopener noreferrer"></a> and select the repository &#8222;<em>ch.hasselba.concurrent</em>&#8222;. Click the &#8222;<em>Clone or download</em>&#8222;-Button and copy the URI from the opening box:</p>
  171. <div id="attachment_2401" style="width: 1004px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2401" src="" alt="" width="994" height="506" srcset=" 994w, 300w, 768w" sizes="(max-width: 994px) 100vw, 994px" /></a><p class="wp-caption-text">Get the repository URI</p></div>
  172. <p>Paste the URI into the location in Eclipse</p>
  173. <div id="attachment_2402" style="width: 541px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2402" src="" alt="" width="531" height="557" srcset=" 531w, 286w" sizes="(max-width: 531px) 100vw, 531px" /></a><p class="wp-caption-text">Add the URI to Eclipse</p></div>
  174. <p>In the next dialog, you can choose the branch to import. In this case, only &#8222;<em>master</em>&#8220; exists</p>
  175. <div id="attachment_2403" style="width: 542px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2403" src="" alt="" width="532" height="557" srcset=" 532w, 287w" sizes="(max-width: 532px) 100vw, 532px" /></a><p class="wp-caption-text">Select the branch to import</p></div>
  176. <p>Now you have to choose a local destination where the cloned repository will be stored</p>
  177. <div id="attachment_2404" style="width: 538px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2404" src="" alt="" width="528" height="552" srcset=" 528w, 287w" sizes="(max-width: 528px) 100vw, 528px" /></a><p class="wp-caption-text">Select the local destination</p></div>
  178. <p>Select &#8222;<em>Import existing Eclipse projects</em>&#8222;&#8230;</p>
  179. <div id="attachment_2405" style="width: 541px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2405" src="" alt="" width="531" height="555" srcset=" 531w, 287w" sizes="(max-width: 531px) 100vw, 531px" /></a><p class="wp-caption-text">Import existing projects</p></div>
  180. <p>&#8230; and select all projects of the repository:</p>
  181. <div id="attachment_2406" style="width: 538px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2406" src="" alt="" width="528" height="558" srcset=" 528w, 284w" sizes="(max-width: 528px) 100vw, 528px" /></a><p class="wp-caption-text">Select all projects</p></div>
  182. <p>With &#8222;<em>Finish</em>&#8222;, the sources are downloaded. In the &#8222;<em>Project Explorer</em>&#8222;, you can see the three imported projects. And you can see the original repository name and the current branch you are working on:</p>
  183. <div id="attachment_2407" style="width: 452px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2407" src="" alt="" width="442" height="212" srcset=" 442w, 300w" sizes="(max-width: 442px) 100vw, 442px" /></a><p class="wp-caption-text">Repository &amp; Branch</p></div>
  184. <p>The JRE used for the project can be seen if you expand one of the projects. &#8222;Sometimes&#8220; this changes magically, and the build will fail &#8211; that is one of the first things you have to check if you have errors in a OSGi project.</p>
  185. <div id="attachment_2408" style="width: 432px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2408" src="" alt="" width="422" height="261" srcset=" 422w, 300w" sizes="(max-width: 422px) 100vw, 422px" /></a><p class="wp-caption-text">JRE / Target used for this project</p></div>
  186. <p>Now, do the same for the &#8222;<em>domino-rest-servlet</em>&#8220; repository. But instead importing the &#8222;<em>master</em>&#8220; branch, select the &#8222;<em>highperformance</em>&#8220; branch only.</p>
  187. <div id="attachment_2409" style="width: 565px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2409" src="" alt="" width="555" height="556" srcset=" 555w, 150w, 300w" sizes="(max-width: 555px) 100vw, 555px" /></a><p class="wp-caption-text">Import HighPerformance Branch</p></div>
  188. <p>That&#8217;s it. In the next post, we have take a look in what you have downloaded.</p>
  189. ]]></content:encoded>
  190. <wfw:commentRss>;p=2397</wfw:commentRss>
  191. <slash:comments>4</slash:comments>
  192. </item>
  193. <item>
  194. <title>High Performance REST Applications (2) – Dev Environment</title>
  195. <link></link>
  196. <comments></comments>
  197. <pubDate>Sun, 23 Apr 2017 08:55:52 +0000</pubDate>
  198. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  199. <category><![CDATA[Java]]></category>
  200. <category><![CDATA[JEE]]></category>
  201. <category><![CDATA[Performance]]></category>
  202. <category><![CDATA[REST]]></category>
  203. <category><![CDATA[Web]]></category>
  204. <category><![CDATA[Domino]]></category>
  205. <category><![CDATA[HTTP]]></category>
  206. <category><![CDATA[OSGi]]></category>
  207. <category><![CDATA[Server]]></category>
  209. <guid isPermaLink="false"></guid>
  210. <description><![CDATA[Before you can start developing a Servlet as an OSGi Plugins, you must set up a development environment first. To do this, download Eclipse IDE (Eclipse IDE for Java EE Developers) and XPages SDK from OpenNTF (The XPages SDK is &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  211. <content:encoded><![CDATA[<p>Before you can start developing a Servlet as an OSGi Plugins, you must set up a development environment first. To do this, download Eclipse IDE (<a title="Tools for Java developers creating Java EE and Web applications, including a Java IDE, tools for Java EE, JPA, JSF, Mylyn, EGit and others." href="">Eclipse IDE for Java EE Developers</a>) and <a href="" target="_blank" rel="noopener noreferrer">XPages SDK</a> from OpenNTF (The XPages SDK is a helper to create the JRE environment and the Target Platform). For development it is the best to have a (local) development server, because during development you might want to restart and/or modify it, and debugging is a lot easier if have control over the whole server.</p>
  212. <p>After unpacking Eclipse and the XPages SDK, you have to install it and set up the JRE and the Target Platform. Go to &#8222;Help &gt; Install New Software&#8220;. With &#8222;Add&#8230;&#8220;, you can add the UpdateSite of the XPages SDK to Eclipse:</p>
  213. <div id="attachment_2379" style="width: 321px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2379" src="" alt="" width="311" height="371" srcset=" 311w, 251w" sizes="(max-width: 311px) 100vw, 311px" /></a><p class="wp-caption-text">Install New Software</p></div>
  214. <div id="attachment_2380" style="width: 895px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2380" src="" alt="" width="885" height="344" srcset=" 885w, 300w, 768w" sizes="(max-width: 885px) 100vw, 885px" /></a><p class="wp-caption-text">Add Update Site</p></div>
  215. <p>Click on &#8222;Local&#8230;&#8220;, and choose the folder &#8222;org.openntf.xsp.sdk.updatesite&#8220; from the unpacked archive. Then give it a name for identification. You can choose whatever you want.</p>
  216. <div id="attachment_2381" style="width: 490px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2381" src="" alt="" width="480" height="180" srcset=" 480w, 300w" sizes="(max-width: 480px) 100vw, 480px" /></a><p class="wp-caption-text">Choose the XPages SDK UpdateSite</p></div>
  217. <p>Now, choose the plugin, click &#8222;OK&#8220;, accept the license, allow the installation from unsigned content and restart Eclipse after installation is complete.</p>
  218. <div id="attachment_2382" style="width: 894px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2382" src="" alt="" width="884" height="695" srcset=" 884w, 300w, 768w" sizes="(max-width: 884px) 100vw, 884px" /></a><p class="wp-caption-text">Install the Plugin</p></div>
  219. <p>Next step ist to configure the JRE: Go to &#8222;Window &gt; Preferences&#8220;, &#8222;XPages SDK&#8220;, and choose the pathes were your Domino Server is installed. Also choose &#8222;Automatically create JRE for Domino&#8220;:</p>
  220. <p><a href=""><img class="alignnone size-full wp-image-2383" src="" alt="" width="171" height="231" /></a></p>
  221. <p><a href=""><img class="alignnone size-full wp-image-2384" src="" alt="" width="638" height="642" srcset=" 638w, 150w, 298w" sizes="(max-width: 638px) 100vw, 638px" /></a></p>
  222. <p>Then apply it.</p>
  223. <p>If you have FP8 installed, you don&#8217;t need the next step: Change the Complier compliance level to 1.6. Again, apply the setting and allow a full rebuild of the Workspace.</p>
  224. <div id="attachment_2385" style="width: 708px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2385" src="" alt="" width="698" height="643" srcset=" 698w, 300w" sizes="(max-width: 698px) 100vw, 698px" /></a><p class="wp-caption-text">Change the compliance level</p></div>
  225. <p>Switch the default JRE to the newly created XPages Domino JRE:</p>
  226. <p><a href=""><img class="alignnone size-full wp-image-2386" src="" alt="" width="699" height="643" srcset=" 699w, 300w" sizes="(max-width: 699px) 100vw, 699px" /></a></p>
  227. <p>Now you have to add the target platform: Enter &#8222;target&#8220; in the search field, select the &#8222;Target Platform&#8220;, and click on &#8222;Add&#8220;. Choose the &#8222;Domino Install Target&#8220;, create it and choose it as active platform.</p>
  228. <div id="attachment_2388" style="width: 731px" class="wp-caption alignnone"><a href=""><img class="size-full wp-image-2388" src="" alt="" width="721" height="681" srcset=" 721w, 300w" sizes="(max-width: 721px) 100vw, 721px" /></a><p class="wp-caption-text">Target Definition: &#8222;Domino Install Target&#8220;</p></div>
  229. <p><a href=""><img class="alignnone size-full wp-image-2387" src="" alt="" width="700" height="646" srcset=" 700w, 300w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
  230. <p>OK, that&#8217;s it. You have a working IDE and you are ready to import the starter project from GitHub.</p>
  231. ]]></content:encoded>
  232. <wfw:commentRss>;p=2376</wfw:commentRss>
  233. <slash:comments>1</slash:comments>
  234. </item>
  235. <item>
  236. <title>High Performance REST Applications (1) &#8211; Intro</title>
  237. <link></link>
  238. <comments></comments>
  239. <pubDate>Fri, 21 Apr 2017 09:33:58 +0000</pubDate>
  240. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  241. <category><![CDATA[Java]]></category>
  242. <category><![CDATA[JEE]]></category>
  243. <category><![CDATA[Performance]]></category>
  244. <category><![CDATA[REST]]></category>
  245. <category><![CDATA[Domino]]></category>
  246. <category><![CDATA[OSGi]]></category>
  247. <category><![CDATA[Server]]></category>
  248. <category><![CDATA[Web]]></category>
  250. <guid isPermaLink="false"></guid>
  251. <description><![CDATA[This is a new serie about developing high performance REST applications on top of Domino. It will contain my presentations from SNoUG and EntwicklerCamp this year and describes all required steps to develop, build and deploy these servlets on a &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  252. <content:encoded><![CDATA[<p>This is a new serie about developing high performance REST applications on top of Domino. It will contain my presentations from <a href="" target="_blank" rel="noopener noreferrer">SNoUG</a> and <a href="" target="_blank" rel="noopener noreferrer">EntwicklerCamp</a> this year and describes all required steps to develop, build and deploy these servlets on a basic level.</p>
  253. <p>The code used in this serie is already available at GitHub:</p>
  254. <ul>
  255. <li><a href="" target="_blank" rel="noopener noreferrer"></a></li>
  256. <li><a href="" target="_blank" rel="noopener noreferrer"></a></li>
  257. </ul>
  258. <p>(The high performance part is in a branch of my example Domino REST Servlet described <a href="" target="_blank" rel="noopener noreferrer">earlier</a> in this blog.)</p>
  259. <p>The serie will start with setting up the development environment, explaining OSGi plugin basics and will then go over how to implement the REST API. Some details about concurrency developments and their problems will also be included. Hopefully it is easy to understand.</p>
  260. <p>Don&#8217;t hold back to ask a question in the comments or to contact me directly. I have kicked out the buggy comment plugin last month, so you should be able to post them even when I have updated my wordpress installation.</p>
  261. <p>Relax and enjoy the upcoming posts.</p>
  262. ]]></content:encoded>
  263. <wfw:commentRss>;p=2370</wfw:commentRss>
  264. <slash:comments>1</slash:comments>
  265. </item>
  266. <item>
  267. <title>Re: Domino REST performance analysis</title>
  268. <link></link>
  269. <comments></comments>
  270. <pubDate>Thu, 16 Mar 2017 20:51:54 +0000</pubDate>
  271. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  272. <category><![CDATA[REST]]></category>
  273. <category><![CDATA[Domino]]></category>
  274. <category><![CDATA[Performance]]></category>
  275. <category><![CDATA[Web]]></category>
  277. <guid isPermaLink="false"></guid>
  278. <description><![CDATA[I have created a Quick-n-Dirty performance test for Csaba&#8217;s &#8222;10K record test&#8220;: Loading time 200 ms overall, 60 ms TTFB. Do you want to know how this works? Feel free to come to SNoUG next week or to Rudi&#8217;s EntwicklerCamp and &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  279. <content:encoded><![CDATA[<p>I have created a Quick-n-Dirty performance test for <a href="" target="_blank">Csaba&#8217;s &#8222;10K record test&#8220;</a>:</p>
  280. <p><a href=""><img class="alignnone size-full wp-image-2365" src="" alt="" width="1361" height="369" srcset=" 1361w, 300w, 768w, 1024w" sizes="(max-width: 1361px) 100vw, 1361px" /></a></p>
  281. <p>Loading time 200 ms overall, 60 ms TTFB.</p>
  282. <p>Do you want to know how this works? Feel free to come to <a href="" target="_blank">SNoUG</a> next week or to Rudi&#8217;s <a href="" target="_blank">EntwicklerCamp</a> and join my sessions about &#8222;High Performance REST Applications&#8220;.</p>
  283. ]]></content:encoded>
  284. <wfw:commentRss>;p=2364</wfw:commentRss>
  285. <slash:comments>6</slash:comments>
  286. </item>
  287. <item>
  288. <title>Domino &#038; Java 1.8: Thank you, IBM!</title>
  289. <link></link>
  290. <comments></comments>
  291. <pubDate>Tue, 14 Mar 2017 13:16:13 +0000</pubDate>
  292. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  293. <category><![CDATA[Java]]></category>
  294. <category><![CDATA[Domino]]></category>
  295. <category><![CDATA[FP 8]]></category>
  296. <category><![CDATA[Java 8]]></category>
  297. <category><![CDATA[Maven]]></category>
  299. <guid isPermaLink="false"></guid>
  300. <description><![CDATA[For years it was a lot of pain when developing for the Domino platform using Java 1.6 only. But now, Java 1.8 is available, and this allows to use the latest versions for a lot of libraries and development tools. &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  301. <content:encoded><![CDATA[<p>For years it was a lot of pain when developing for the Domino platform using Java 1.6 only. But now, Java 1.8 is available, and this allows to use the latest versions for a lot of libraries and development tools.</p>
  302. <p>After installing FP8 to the Client, Eclipse allowes to use the Domino JRE in a JavaSE-1.8 environment:</p>
  303. <p><a href=""><img class="alignnone size-full wp-image-2356" src="" alt="" width="824" height="556" srcset=" 824w, 300w, 768w" sizes="(max-width: 824px) 100vw, 824px" /></a></p>
  304. <p>This gives access to the latest <a href="" target="_blank">M2Eclipse plugin (1.7.0)</a>. The old version problem when running with JRE 1.6&#8230;</p>
  305. <p><a href=""><img class="alignnone size-full wp-image-2357" src="" alt="" width="1113" height="277" srcset=" 1113w, 300w, 768w, 1024w" sizes="(max-width: 1113px) 100vw, 1113px" /></a>&#8230; is solved:</p>
  306. <p><a href=""><img class="alignnone size-full wp-image-2358" src="" alt="" width="678" height="255" srcset=" 678w, 300w" sizes="(max-width: 678px) 100vw, 678px" /></a></p>
  307. <p>Eclipse Updates? No problem, just do it!</p>
  308. <p>Latest Java features like switch statement with Strings? Here we go:</p>
  309. <pre><code>String token = "FOO";
  310. switch(token) {
  311.    case "FOO": return (T) Foo.class;
  312.    case "BAR": return (T) Bar.class;
  313. }</code></pre>
  314. <p>Third party libraries like Jackson 2.8.0? Works like a charm!</p>
  315. <p>Thank you, IBM!</p>
  316. ]]></content:encoded>
  317. <wfw:commentRss>;p=2353</wfw:commentRss>
  318. <slash:comments>0</slash:comments>
  319. </item>
  320. <item>
  321. <title>Domino &#038; REST: Debug your Plugin</title>
  322. <link></link>
  323. <comments></comments>
  324. <pubDate>Tue, 07 Mar 2017 11:14:02 +0000</pubDate>
  325. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  326. <category><![CDATA[Jackson]]></category>
  327. <category><![CDATA[Java]]></category>
  328. <category><![CDATA[JEE]]></category>
  329. <category><![CDATA[OSGi]]></category>
  330. <category><![CDATA[REST]]></category>
  331. <category><![CDATA[Apache Wink]]></category>
  332. <category><![CDATA[Domino]]></category>
  333. <category><![CDATA[Server]]></category>
  335. <guid isPermaLink="false"></guid>
  336. <description><![CDATA[When developing OSGi Plugins, you should have your own development server running on your local machine. Not only because of the faster deployment of changes (a new version of a plugin must always deployed with a HTTP restart), but because &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  337. <content:encoded><![CDATA[<p>When developing OSGi Plugins, you should have your own development server running on your local machine. Not only because of the faster deployment of changes (a new version of a plugin must always deployed with a HTTP restart), but because of the Java debugging posibilities: Only one Eclipse instance can connect to the JVM, and every request processed by the server will start the debugger. If multiple users a accessing the server while you are debugging, your Eclipse will try to debug every incoming request, and this can lead into a confusing situation for all.</p>
  338. <p>To enable debugging, you first have to add two parameters to the <em>notes.ini</em>:</p>
  339. <pre><code>JavaEnableDebug=1
  340. JavaDebugOptions=transport=dt_socket,server=y,suspend=n,address=8000</code></pre>
  341. <p>This starts the debugging on port 8000. Feel free to change the value to every port you want. Because of security reasons you should not start debugging on a productive machine.</p>
  342. <p>After restarting the domino server, you can connect to the JVM in your Eclipse IDE by creating a new JVM remote debugging session. Create a new debug configuration&#8230;</p>
  343. <p><a href=""><img class="alignnone size-full wp-image-2337" src="" alt="" width="270" height="133" /></a></p>
  344. <p>&#8230; choose (1) &#8222;<em>Remote Java Application</em>&#8222;, (2) give a name to it, (3) select the plugin project, (4) enter the port the server listens, and click on (5) &#8222;<em>Apply</em>&#8222;.</p>
  345. <p><a href=""><img class="alignnone size-full wp-image-2340" src="" alt="" width="862" height="537" srcset=" 862w, 300w, 768w" sizes="(max-width: 862px) 100vw, 862px" /></a></p>
  346. <p>If you want to connect to your server, you need to start debugging by clicking on the project:</p>
  347. <p><a href=""><img class="alignnone size-full wp-image-2341" src="" alt="" width="221" height="129" /></a></p>
  348. <p>After setting a breakpoint and sending a request to the servlet, Eclipse switches to the Debug perspective where you can look what happens with your servlet.</p>
  349. <p><a href=""><img class="alignnone size-full wp-image-2344" src="" alt="" width="491" height="485" srcset=" 491w, 300w" sizes="(max-width: 491px) 100vw, 491px" /></a></p>
  350. <p>Sometimes you are connecting to the &#8222;wrong&#8220; JVM, because a Java agent is running and/or a DOTS task does it&#8217;s job. It&#8217;s better to disable these tasks on your development server.</p>
  351. <p>During debugging you are able to <a href="" target="_blank">hotswap your code</a>, but keep in mind that after a restart of the HTTP JVM all your changes are no longer &#8222;installed&#8220;. You have to build a new plugin or replace your code during runtime again.</p>
  352. <p>In the next blog post, let&#8217;s talk about our development tools.</p>
  353. ]]></content:encoded>
  354. <wfw:commentRss>;p=2326</wfw:commentRss>
  355. <slash:comments>0</slash:comments>
  356. </item>
  357. <item>
  358. <title>Domino &#038; REST: More about Jackson</title>
  359. <link></link>
  360. <comments></comments>
  361. <pubDate>Fri, 03 Mar 2017 10:16:30 +0000</pubDate>
  362. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  363. <category><![CDATA[Apache Wink]]></category>
  364. <category><![CDATA[Jackson]]></category>
  365. <category><![CDATA[JEE]]></category>
  366. <category><![CDATA[REST]]></category>
  367. <category><![CDATA[Domino]]></category>
  368. <category><![CDATA[Web]]></category>
  370. <guid isPermaLink="false"></guid>
  371. <description><![CDATA[When creating a REST API servlet, Jackson provides a huge list of possibilities to manipulate the JSON data, mostly using annotations. Let&#8217;s demonstrate some of them with this little class, which has only two properties: public class Demo { private String foo; &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  372. <content:encoded><![CDATA[<p style="text-align: left;">When creating a REST API servlet, Jackson provides a huge list of possibilities to manipulate the JSON data, mostly using annotations.</p>
  373. <p>Let&#8217;s demonstrate some of them with this little class, which has only two properties:</p>
  374. <pre><code>public class Demo {
  376.    private String foo;
  377. </code><code>    private String bar;
  379. </code><code>    public String getFoo() {
  380.        return foo;
  381.    }
  382.    public void setFoo(String foo) {
  383. = foo;
  384.    }
  386. </code><code>    public String getBar() {
  387.        return bar;
  388.    }
  390.    public void setBar(String bar) {
  391. = bar;
  392.    }</code><code>
  393. }</code></pre>
  394. <p>The playground converts the <em>content</em> string to a POJO and back to a string:</p>
  395. <pre><code>String content = "{ \"foo\": \"bar\" }";
  396. // init the ObjectMapper
  397. ObjectMapper mapper = new ObjectMapper();
  398. // build the Object
  399. Demo test = null;
  400. try {
  401.     test = mapper.readValue(content, Demo.class);
  402. } catch (Exception e) {
  403.     e.printStackTrace();
  404. }
  406. // and now convert it back to a String
  407. String data = null;
  408. try {
  409.     data = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(test);
  410. } catch (Exception e) {
  411.     e.printStackTrace();
  412. }
  414. System.out.println( data );</code></pre>
  415. <p>If we run this code, the result is not really spectacular:</p>
  416. <pre><code>{
  417. "foo" : "bar",
  418. "bar" : null
  419. }</code></pre>
  420. <p>So let&#8217;s ignore the property foo by adding the annotation <em>@JsonIgnoreProperties</em> to the <em>Demo</em> class:</p>
  421. <pre><code>@JsonIgnoreProperties({"foo"})
  422. public class Demo { ... }</code></pre>
  423. <p>Now, <em>foo</em> is no longer in our resulting JSON:</p>
  424. <pre><code>{
  425.    "bar" : null
  426. }</code></pre>
  427. <p>The property <em>bar</em> is null, and we don&#8217;t like nulled properties in our JSON. That&#8217;s why we add another annotation, <em>@JsonInclude</em>:</p>
  428. <pre><code>@JsonInclude(JsonInclude.Include.NON_EMPTY)
  429. public class Demo { ... }</code></pre>
  430. <p>After removing the previously added <em>@JsonIgnoreProperties</em> annotation, our result looks like this (the empty property <em>bar</em> was skipped):</p>
  431. <pre><code>{
  432.    "foo" : "bar"
  433. }</code></pre>
  434. <p>What happens if we change our <em>content</em> string, and add an unknown property?</p>
  435. <pre><code>String content = "{ \"foo\": \"bar\", \"undefined\": \"property\" }";</code></pre>
  436. <p>An error occurs because Jackson does not know how to handle the new property:</p>
  437. <pre><code>com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "undefined" (class ch.hasselba.JacksonPlayground.Demo), not marked as ignorable (2 known properties: "foo", "bar"])
  438. at [Source: { "foo": "bar", "undefined": "property" }; line: 1, column: 31] (through reference chain: ch.hasselba.JacksonPlayground.Demo["undefined"])
  439. at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(
  440. at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(
  441. at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(
  442. at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(
  443. at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(
  444. at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(
  445. at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(
  446. at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(
  447. at com.fasterxml.jackson.databind.ObjectMapper.readValue(
  448. at ch.hasselba.JacksonPlayground.App.main(
  449. null</code></pre>
  450. <p>But there are two annotations to the rescue, <em>@JsonAnyGetter</em> &amp; <em>@JsonAnySetter</em>. By changing our <em>Demo</em> class and adding the following lines of code&#8230;</p>
  451. <pre><code>private Map&lt;String, Object&gt; others = new ConcurrentHashMap&lt;String, Object&gt;();
  453. @JsonAnyGetter
  454. public Map&lt;String, Object&gt; getOthers() {
  455.    return this.others;
  456. }
  458. @JsonAnySetter
  459. public void addOther(final String name, final Object value) {
  460.    this.others.put(name, value);
  461. }</code></pre>
  462. <p>&#8230; Jackson now puts all the unknown/undefined properties in the <em>others</em> map (uses the method defined by <em>@JsonSetter</em>). And then it uses the method with the <em>@JsonGetter</em> annotation when producing the JSON from the Demo instance.</p>
  463. <pre><code>{
  464.  "foo" : "bar",
  465.  "bar" : null,
  466.  "undefined" : "property"
  467. }
  468. </code></pre>
  469. <p>What if we want to handle multiple &#8222;Demo&#8220; objects in a JSON Array?</p>
  470. <pre><code>String content = "[ { \"foo\": \"bar\" }, {\"foo\": \"bar2\" } ]";</code></pre>
  471. <p>In this case we change our reading routine to work with lists:</p>
  472. <pre><code>// build the Object
  473. List&lt;Demo&gt; test = null;
  474. try {
  475.    test = mapper.readValue(content, mapper.getTypeFactory()
  476.            .constructCollectionType(List.class, Demo.class));
  477. } catch (Exception e) {
  478.    e.printStackTrace();
  479. }</code></pre>
  480. <p>In the result all entries are now contained in the list of <em>Demo</em> objects:</p>
  481. <pre><code>[ {
  482. "foo" : "bar",
  483. "bar" : null
  484. }, {
  485. "foo" : "bar2",
  486. "bar" : null
  487. } ]</code></pre>
  488. <p>Back to our <a href="" target="_blank">RestApiApplication</a>, have a look at this line:</p>
  489. <pre><code>objMapper.setSerializationInclusion(Include.NON_EMPTY);</code></pre>
  490. <p>This removes all empty properties globally from the generated output of our the servlet. So there is no need to add the <em>@JsonIgnore</em> annotation to any class. You can modifiy the globally used ObjectMapper in your servlet with multiple option, more will follow in another blog post.</p>
  491. ]]></content:encoded>
  492. <wfw:commentRss>;p=2297</wfw:commentRss>
  493. <slash:comments>0</slash:comments>
  494. </item>
  495. <item>
  496. <title>Domino &#038; REST: Accessing Domino&#8217;s Environment / Check Authentication</title>
  497. <link></link>
  498. <comments></comments>
  499. <pubDate>Thu, 02 Mar 2017 11:00:37 +0000</pubDate>
  500. <dc:creator><![CDATA[Sven Hasselbach]]></dc:creator>
  501. <category><![CDATA[Apache Wink]]></category>
  502. <category><![CDATA[Jackson]]></category>
  503. <category><![CDATA[Java]]></category>
  504. <category><![CDATA[JEE]]></category>
  505. <category><![CDATA[REST]]></category>
  506. <category><![CDATA[Domino]]></category>
  507. <category><![CDATA[HTTP]]></category>
  508. <category><![CDATA[OSGi]]></category>
  509. <category><![CDATA[Web]]></category>
  511. <guid isPermaLink="false"></guid>
  512. <description><![CDATA[If we want to access Domino&#8217;s Environment, it is the ContextInfo class which gives us all we need. Everything you need to do to use the class is described in an earlier blog post. The class gives mainly access to the &#8230; <a href="">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
  513. <content:encoded><![CDATA[<p>If we want to access Domino&#8217;s Environment, it is the <em>ContextInfo </em>class which gives us all we need. Everything you need to do to use the class is described in an <a href="" target="_blank">earlier blog post</a>.</p>
  514. <p>The class gives mainly access to the following methods:</p>
  515. <table style="width: 639px;">
  516. <tbody>
  517. <tr>
  518. <td><strong>Method</strong></td>
  519. <td><strong>Description</strong></td>
  520. </tr>
  521. </tbody>
  522. <tbody>
  523. <tr>
  524. <td style="width: 302.722px;">getDataDirectory()</td>
  525. <td style="width: 239.278px;">Path to notes data directory</td>
  526. </tr>
  527. <tr>
  528. <td style="width: 302.722px;">getEnvironmentString(String envName)</td>
  529. <td style="width: 239.278px;">Returns the environment variable</td>
  530. </tr>
  531. <tr>
  532. <td style="width: 302.722px;">getServerDatabase()</td>
  533. <td style="width: 239.278px;">The actual database as NAPI object, if any</td>
  534. </tr>
  535. <tr>
  536. <td style="width: 302.722px;">getServerVariable(String varName)</td>
  537. <td style="width: 239.278px;">Variables from the Request, i.e. &#8222;QUERY_STRING&#8220;</td>
  538. </tr>
  539. <tr>
  540. <td style="width: 302.722px;">getUserDatabase()</td>
  541. <td style="width: 239.278px;">The actual database as Domino Java object, if any</td>
  542. </tr>
  543. <tr>
  544. <td style="width: 302.722px;">getUserSession()</td>
  545. <td style="width: 239.278px;">The session of the actual user performing the request (</td>
  546. </tr>
  547. <tr>
  548. <td style="width: 302.722px;">isAnonymous()</td>
  549. <td style="width: 239.278px;">true if the current user is Anonymous</td>
  550. </tr>
  551. </tbody>
  552. </table>
  553. <p>Keep in mind that the incoming request is independently of any underlying Notes database. In our example, the URI <em>http://your.server/dominorestservlet/helloworld/ </em>does not run inside of a NSF, that&#8217;s why the <em>getServerDatabase()</em> and the <em>getUserDatabase()</em> methods returns <em>null</em>.</p>
  554. <p>As a consequence, our servlet does not have any access restriction and is reachable as anonymous. If you want to access a database programatically, the &#8222;normal&#8220; Domino access control is intervening again, but we can do the access check by ourself.</p>
  555. <p>To prevent the access to the servlet, I have added a &#8222;<em>checkAuthentication</em>&#8220; method to the <a href="" target="_blank">RestApiServlet</a> class. This method checks if the current user is a) not anonymous and b) a member of the group <em>RESTAPIAccessAllowed</em>. The method throws a <em>NotAuthenticatedException</em> which let&#8217;s the servlet return a <a href="" target="_blank">HTTP 403</a>.</p>
  556. ]]></content:encoded>
  557. <wfw:commentRss>;p=2316</wfw:commentRss>
  558. <slash:comments>2</slash:comments>
  559. </item>
  560. </channel>
  561. </rss>

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid RSS" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda