<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Tambo's Tricks]]></title><description><![CDATA[Blog about development tricks (mostly Java JEE) and tech stuff]]></description><link>https://jerometambo.github.io/blog</link><generator>RSS for Node</generator><lastBuildDate>Sat, 24 Dec 2016 15:53:48 GMT</lastBuildDate><atom:link href="https://jerometambo.github.io/blog/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Fix network TV streaming (Working then nothing) Mediaportal extension with Kodi]]></title><description><![CDATA[<div class="paragraph">
<p>If, like myself, you have a Mediacenter based on Kodi (with Mediaportal for TV server) and you want to watch your TV channels from anywhere, you might have seen the "Working in the wind" problem:</p>
</div>
<div id="img-kodiWorking" class="imageblock">
<div class="content">
<img src="https://jerometambo.github.io/blog/images/kodiTVWorking.png" alt="Kodi" width="400" height="282">
</div>
<div class="title">Figure 1. When you click on your channel</div>
</div>
<div id="img-kodiWorkingNothing" class="imageblock">
<div class="content">
<img src="https://jerometambo.github.io/blog/images/kodiTVWorkingThenNothing.png" alt="Kodi" width="400" height="282">
</div>
<div class="title">Figure 2. And voilà</div>
</div>
<div class="paragraph">
<p>So let&#8217;s read the Kodi&#8217;s logs:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>19:30:52 T:5604  NOTICE: DVDPlayer: Opening: pvr://channels/tv/Toutes les chaînes/pvr.mediaportal.tvserver_17.pvr
19:30:52 T:5604 WARNING: CDVDMessageQueue(player)::Put MSGQ_NOT_INITIALIZED
19:30:52 T:2472  NOTICE: Creating InputStream
19:30:52 T:2472  NOTICE: AddOnLog: MediaPortal PVR Client: Open Live stream for channel uid=17
19:30:53 T:2472  NOTICE: AddOnLog: MediaPortal PVR Client: Channel timeshift buffer: C:\Tv\live3-0.ts.tsbuffer
19:30:53 T:2472  NOTICE: AddOnLog: MediaPortal PVR Client: Creating a new TsReader...
19:30:53 T:2472  NOTICE: AddOnLog: MediaPortal PVR Client: TsReader open 'C:\Tv\live3-0.ts.tsbuffer'
19:30:53 T:2472  NOTICE: AddOnLog: MediaPortal PVR Client: Cannot access 'C:\Tv\live3-0.ts.tsbuffer' directly. Assuming multiseat mode. Need to translate to UNC filename.
19:30:53 T:2472  NOTICE: AddOnLog: MediaPortal PVR Client: Translate path C:\Tv\live3-0.ts.tsbuffer -&gt; smb://kodi:kodi@BBMEDIACENTER/Tv/live3-0.ts.tsbuffer
19:30:53 T:2472   ERROR: AddOnLog: MediaPortal PVR Client: Cannot find or access file: smb://kodi:kodi@BBMEDIACENTER/Tv/live3-0.ts.tsbuffer. Check share access rights.
19:30:53 T:2472   ERROR: AddOnLog: MediaPortal PVR Client: Cannot open timeshift buffer C:\Tv\live3-0.ts.tsbuffer
19:30:53 T:2472  NOTICE: AddOnLog: MediaPortal PVR Client: TsReader: closing file
19:30:54 T:2472  NOTICE: AddOnLog: MediaPortal PVR Client: CloseLiveStream: True
19:30:54 T:2472   ERROR: CDVDPlayer::OpenInputStream - error opening [pvr://channels/tv/Toutes les chaînes/pvr.mediaportal.tvserver_17.pvr]
19:30:54 T:2472  NOTICE: CDVDPlayer::OnExit()
19:30:54 T:5604  NOTICE: CDVDPlayer::CloseFile()
19:30:54 T:5604  NOTICE: DVDPlayer: waiting for threads to exit
19:30:54 T:5604  NOTICE: DVDPlayer: finished waiting
19:30:54 T:5604  NOTICE: CDVDPlayer::CloseFile()</pre>
</div>
</div>
<div class="paragraph">
<p>It seems that TsReader can&#8217;t access the SMB share, even this SMB share works.</p>
</div>
<div class="paragraph">
<p>The simpliest solution to this problem is to chage the streaming library from TsReader to ffmpeg:</p>
</div>
<div id="img-kodiConfig" class="imageblock">
<div class="content">
<img src="https://jerometambo.github.io/blog/images/kodiTVMediaPortalStreamConfig.png" alt="Kodi" width="400" height="282">
</div>
<div class="title">Figure 3. System &#8594; Settings &#8594; Add-ons &#8594; My add-ons &#8594; PVR clients &#8594; MediaPortal PVR Client &#8594; Configure &#8594; Playback</div>
</div>
<div id="img-kodiSuccess" class="imageblock">
<div class="content">
<img src="https://jerometambo.github.io/blog/images/kodiTVffmpeg.png" alt="Kodi" width="400" height="282">
</div>
<div class="title">Figure 4. Success !</div>
</div>
<div class="paragraph">
<p>I hope it can prevent you from nervous crisis with Kodi :).</p>
</div>
<div class="paragraph">
<p>Tchou !</p>
</div>
<div class="paragraph">
<p>Useful links:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://kodi.tv/" class="bare">https://kodi.tv/</a></p>
</li>
<li>
<p><a href="http://www.team-mediaportal.com/" class="bare">http://www.team-mediaportal.com/</a></p>
</li>
</ul>
</div>]]></description><link>https://jerometambo.github.io/blog/2016/12/23/Fix-network-TV-streaming-Working-then-nothing-Mediaportal-extension-with-Kodi.html</link><guid isPermaLink="true">https://jerometambo.github.io/blog/2016/12/23/Fix-network-TV-streaming-Working-then-nothing-Mediaportal-extension-with-Kodi.html</guid><category><![CDATA[Kodi]]></category><category><![CDATA[ Mediaportal]]></category><category><![CDATA[ TV]]></category><category><![CDATA[ Tech]]></category><dc:creator><![CDATA[jerometambo]]></dc:creator><pubDate>Fri, 23 Dec 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[How to use JavaEE 6 upload feature with configurable properties (max filesize, temp directory, etc.) and Tomcat performance tricks]]></title><description><![CDATA[<div class="paragraph">
<p>Since Servlet 3.0 (JavaEE 6), Servlet 3.0 supports two additional HttpServletRequest methods:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Collection&lt;Part&gt; getParts()</pre>
</div>
</div>
<div class="literalblock">
<div class="content">
<pre>Part getPart(String name)</pre>
</div>
</div>
<div class="paragraph">
<p>With this, you don&#8217;t need  other library anymore to perform some file uploads.</p>
</div>
<div class="paragraph">
<p>To set the upload properties, you can use the <em>@MultipartConfig</em> annotation. The <em>@MultipartConfig</em> annotation indicates that the servlet expects requests to be made using the multipart/form-data MIME type. Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">@MultipartConfig(location="/tmp", fileSizeThreshold=1024*1024,
    maxFileSize=1024*1024*5, maxRequestSize=1024*1024*5*5)</code></pre>
</div>
</div>
<div class="paragraph">
<p>Instead of using the <em>@MultipartConfig</em> annotation to hard-code these attributes in your file upload servlet, you could add the following as a child element of the servlet configuration element in the web.xml file:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;multipart-config&gt;
    &lt;location&gt;/tmp&lt;/location&gt;
    &lt;max-file-size&gt;20848820&lt;/max-file-size&gt;
    &lt;max-request-size&gt;418018841&lt;/max-request-size&gt;
    &lt;file-size-threshold&gt;1048576&lt;/file-size-threshold&gt;
&lt;/multipart-config&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>But if you want to set dynamically your upload settings (via properties for example) from your java code, you&#8217;re stuck.
Using the Dynamic servlet registration as described in my previous post, you can instanciate the configuration object and set whatever you want:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">package org.jerometambo.dynamicservletinitializer.servlet;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration.Dynamic;

/**
 * Servlets initialization.
 */
public class DynamicServletInitializer implements ServletContextListener {

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        final int size = Parameters.UPLOAD_SIZE_LIMIT * 1024; //from wherever you want
        Dynamic registered = servletContextEvent.getServletContext().addServlet("HelloWorld", HelloWorld.class);
        registered.addMapping("/HelloWorld");
        registered.setMultipartConfig(new MultipartConfigElement(Parameters.UPLOAD_TEMP_DIR, size, size, size));
    }

    public void contextDestroyed(ServletContextEvent sce) {

    }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can find an example on my github: <a href="https://github.com/jerometambo/dynamicservletinitializer" class="bare">https://github.com/jerometambo/dynamicservletinitializer</a> on the <em>uploadConfigFromProperties</em> branch.</p>
</div>
<div class="paragraph">
<p>You can find an utils lib to deal with <em>File</em> uploads on my github: <a href="https://github.com/jerometambo/javaeeuploadutils" class="bare">https://github.com/jerometambo/javaeeuploadutils</a> on the <em>master</em> branch.</p>
</div>
<div class="paragraph">
<p>Useful links:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="http://docs.oracle.com/javaee/6/tutorial/doc/glrbb.html" class="bare">http://docs.oracle.com/javaee/6/tutorial/doc/glrbb.html</a></p>
</li>
<li>
<p><a href="https://docs.oracle.com/javaee/7/tutorial/servlets016.htm" class="bare">https://docs.oracle.com/javaee/7/tutorial/servlets016.htm</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Tchou !</p>
</div>]]></description><link>https://jerometambo.github.io/blog/2016/12/20/How-to-use-JavaEE-6-upload-feature-with-configurable-properties-max-filesize-temp-directory-etc-and-Tomcat-performance-tricks.html</link><guid isPermaLink="true">https://jerometambo.github.io/blog/2016/12/20/How-to-use-JavaEE-6-upload-feature-with-configurable-properties-max-filesize-temp-directory-etc-and-Tomcat-performance-tricks.html</guid><category><![CDATA[Upload]]></category><category><![CDATA[ Tomcat 7]]></category><category><![CDATA[ Tomcat 8]]></category><category><![CDATA[ Servlet 3.0]]></category><category><![CDATA[ Java EE]]></category><category><![CDATA[ Programming]]></category><dc:creator><![CDATA[jerometambo]]></dc:creator><pubDate>Tue, 20 Dec 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[How to dynamically register a Servlet (SCI since Servlet 3.0) with Tomcat 7 / 8 speed-up optimization]]></title><description><![CDATA[<div class="paragraph">
<p>Since Tomcat 7, and it&#8217;s even worth with Tomcat 8, the time to start up a webapp has seriously increased. There are 2 excellent posts about how to speed-up the start-up of a webapp in Tomcat by changing your webapp configuration (mostly web.xml) :</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://wiki.apache.org/tomcat/HowTo/FasterStartUp" class="bare">https://wiki.apache.org/tomcat/HowTo/FasterStartUp</a></p>
</li>
<li>
<p><a href="https://tcollignon.github.io/2016/02/09/Accelerate-tomcat-78-start-up.html" class="bare">https://tcollignon.github.io/2016/02/09/Accelerate-tomcat-78-start-up.html</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If you exclude JARs from scanning in Tomcat, you will not be able to perform some dynamic registration of Servlet via the @WebListener annotation a ServletContextListener implementation :</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-java" data-lang="java">package org.jerometambo.dynamicservletinitializer.servlet;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration.Dynamic;

/**
 * Then register the main {@link Servlet}. Inject configurations like {@link MultipartConfigElement}.
 */
@WebListener
public class DynamicServletInitializer implements ServletContextListener {
  /** The main {@link Servlet} name. */
  public static final String MAIN_SERVLET = "HelloWorld";
  /** The main error page name. */
  public static final String ERROR_PAGE = "errorPage";

  @Override
  public void contextInitialized(ServletContextEvent servletContextEvent) {
	registerMainServlet(servletContextEvent);
  }

  /**
   * Registers the main servlet in application.
   */
  protected void registerMainServlet(ServletContextEvent servletContextEvent) {
    Dynamic registered = servletContextEvent.getServletContext().addServlet(MAIN_SERVLET, HelloWorldServlet.class);
    registered.addMapping("/HelloWorld");
    registered.setInitParameter(ERROR_PAGE, getErrorPage());
  }

  /**
   * @return the relative path of the error page in application.
   */
  protected String getErrorPage() {
    return "/jsp/org/jerometambo/errorPage.jsp";
  }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The trick in order to be able to use SCI and features like this one with Tomcat 7/8 tuning, is to declare your listener in your web.xml:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
&lt;web-app metadata-complete="true"&gt;
&lt;absolute-ordering /&gt;
  &lt;!-- ... --&gt;
    &lt;listener&gt;
  &lt;!-- we don't use @WebListener annotation otherwise Tomcat has to scan JARs at start-up --&gt;
    &lt;listener-class&gt;org.jerometambo.dynamicservletinitializer.servlet.DynamicServletInitializer&lt;/listener-class&gt;
  &lt;/listener&gt;
  &lt;!-- ... --&gt;
&lt;/web-app&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can find an example on my github: <a href="https://github.com/jerometambo/dynamicservletinitializer" class="bare">https://github.com/jerometambo/dynamicservletinitializer</a> on the <em>master</em> branch.</p>
</div>
<div class="paragraph">
<p>I hope it can help you to fasten up your applications start-up.</p>
</div>
<div class="paragraph">
<p>Tchou !</p>
</div>]]></description><link>https://jerometambo.github.io/blog/2016/12/15/How-to-dynamically-register-a-Servlet-SCI-since-Servlet-30-with-Tomcat-7-8-speed-up-optimization.html</link><guid isPermaLink="true">https://jerometambo.github.io/blog/2016/12/15/How-to-dynamically-register-a-Servlet-SCI-since-Servlet-30-with-Tomcat-7-8-speed-up-optimization.html</guid><category><![CDATA[Tomcat 7]]></category><category><![CDATA[ Tomcat 8]]></category><category><![CDATA[ Servlet 3.0]]></category><category><![CDATA[ Java]]></category><category><![CDATA[ Programming]]></category><dc:creator><![CDATA[jerometambo]]></dc:creator><pubDate>Thu, 15 Dec 2016 00:00:00 GMT</pubDate></item><item><title><![CDATA[How to use CXF 3.x implementation of JAX-RS 2.0 (REST) with Weblogic 12c]]></title><description><![CDATA[<div class="paragraph">
<p>When I had to deploy a webapp with REST web services based on CXF 3.x on Weblogic 12c server, my problems started. With default configuration, Weblogic wants to use its internal implementation (JAX-RS 2.0 and serialization) to deploy the REST web services (Error 500):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-asciidoc" data-lang="asciidoc">java.lang.LinkageError: ClassCastException: attempting to castjar:file:/opt/weblogic/oracle_common/modules/javax.ws.rs.javax.ws.rs-api.jar!/javax/ws/rs/ext/RuntimeDelegate.class to jar:file:/opt/weblogic/oracle_common/modules/javax.ws.rs.javax.ws.rs-api.jar!/javax/ws/rs/ext/RuntimeDelegate.class

at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:146)

at javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:120)

at javax.ws.rs.core.Response$ResponseBuilder.newInstance(Response.java:848)

at javax.ws.rs.core.Response.status(Response.java:590)

at javax.ws.rs.core.Response.status(Response.java:601)</code></pre>
</div>
</div>
<div class="paragraph">
<p>After many researches and the reading of Oracle posts (I even tried to open a SR at Oracle but it wasn&#8217;t really helpful this time), I manage to find a working configuration. This configuration sets Weblogic not to choose its own implementations for web services deployment and resources serialization.</p>
</div>
<div class="paragraph">
<p>To let CXF works (and Jackson here for the serialization side), you have to change these configuration files:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>../webapp/WEB-INF/weblogic.xml :</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;weblogic-web-app  xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app
                                       http://xmlns.oracle.com/weblogic/weblogic-web-app/1.8/weblogic-web-app.xsd"&gt;
&lt;!-- ... --&gt;
&lt;container-descriptor&gt;
	&lt;prefer-application-packages&gt;
		&lt;package-name&gt;javax.ws.rs.*&lt;/package-name&gt;
		&lt;package-name&gt;com.fasterxml.jackson.*&lt;/package-name&gt; &lt;!-- Your root serialization implementation package --&gt;
	&lt;/prefer-application-packages&gt;
	&lt;!-- ... --&gt;
&lt;/container-descriptor&gt;</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>../META-INF/weblogic-application.xml</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-xml" data-lang="xml">&lt;wls:weblogic-application  xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-application"
                           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                           xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-application
                                               http://xmlns.oracle.com/weblogic/weblogic-application/1.8/weblogic-application.xsd"&gt;

    &lt;wls:prefer-application-packages&gt;
      &lt;wls:package-name&gt;javax.ws.rs.*&lt;/wls:package-name&gt;
      &lt;wls:package-name&gt;com.fasterxml.jackson.*&lt;/wls:package-name&gt;
      &lt;wls:package-name&gt;weblogic.jaxrs.api.client.*&lt;/wls:package-name&gt;
      &lt;wls:package-name&gt;weblogic.jaxrs.internal.api.*&lt;/wls:package-name&gt;
      &lt;wls:package-name&gt;weblogic.jaxrs.dispatch.*&lt;/wls:package-name&gt;
      &lt;wls:package-name&gt;weblogic.jaxrs.monitoring.util.*&lt;/wls:package-name&gt;
    &lt;/wls:prefer-application-packages&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>I hope this can help some REST web services developers with CXF 3 who have to deal with Weblogic 12c :)</p>
</div>
<div class="paragraph">
<p>Tchou !</p>
</div>]]></description><link>https://jerometambo.github.io/blog/2016/12/13/How-to-use-CXF-3x-implementation-of-JAX-RS-20-REST-with-Weblogic-12c.html</link><guid isPermaLink="true">https://jerometambo.github.io/blog/2016/12/13/How-to-use-CXF-3x-implementation-of-JAX-RS-20-REST-with-Weblogic-12c.html</guid><category><![CDATA[REST]]></category><category><![CDATA[ Weblogic 12c]]></category><category><![CDATA[ CXF 3]]></category><category><![CDATA[ Java]]></category><category><![CDATA[ Programming]]></category><dc:creator><![CDATA[jerometambo]]></dc:creator><pubDate>Tue, 13 Dec 2016 00:00:00 GMT</pubDate></item></channel></rss>