Remote access to Serviio DB

Serviio is a simply great DLNA server, supporting a lot of DLNA clients out-of-the-box. Since Serviio saves the metadata in an embedded (!) Apache Derby DB, it’s easy to access it using a JDBC-enabled DB client, for example SquirrelSQL (of course, on its own risk – damaging the DB will result in unexpected behavior and potential loss of data… SQL knowledge is mandatory…).

Please notice: Don’t try to modify the metadata of the media library by editing the Derby DB. Your modifications won’t be persistent, because Serviio will update the DB on the next metadata scraping based on nfo files (or other metadata sources defined using the control panel). So, the correct way to feed your own metadata to Serviio’s db is to provide, e.g, nfo files. I’ve described in a different blog entry how to create nfo files from vsmeta (Synology Video Station) metadata.

To access the Serviio DB remotely, the following steps should work (i assume serviio runs on a Debian Stretch box):

    1. Stop the serviio service, otherwise you won’t be able to access the DB remotely.
    2. Install derbytools (providing the required jars to run a derby server).
    3. Check the version of derbytools. This is important because a version mismatch between server and client may lead to strange errors. To do so:
      • Set the classpath:
        export CLASSPATH=/usr/share/java/derbytools.jar:/usr/share/java/derbyclient.jar
      • Run the derby cli:
        java org.apache.derby.tools.ij
      • First line of ij output will be something like "IJ-Version 10.13" – notice the 10.13.
      • Exist ij with
        QUIT;
    4. Start a Derby Server in Serviio’s library root. It’s important that the server process has write access to the db files, so it should be run as user serviio. Depending on the server os, the path to derbynet.jar may be different.
      • cd /opt/serviio/library
      • sudo -u serviio java -jar /usr/share/java/derbynet.jar start -h 0.0.0.0 &
    5. Try to connect locally:
        • Run the derby cli:
          java org.apache.derby.tools.ij
        • Connect to db:
          connect 'jdbc:derby://localhost:1527/db';
        • Display some data:
          SHOW SCHEMAS;
        • Exit ij:
          QUIT;
    6. If this works, before trying to connect remotely, prepare the client so it’s equipped with the same Derby version as the server. Double-check by repeating step 3 (above) on the client.
    7. Now, try to connect from the client. Repeat step 5 on the client, replacing localhost with the server name or ip.
    8. If you’re done working with the client, as last steps:
      • stop the derby server:
        sudo -u serviio java -jar /usr/share/java/derbynet.jar stop -h 0.0.0.0 &
      • and restart the serviio process again.

Apache Derby: connecting remote server fails – java.lang.NoSuchMethodError: java.nio.ByteBuffer.clear()Ljava/nio/ByteBuffer

Trying to connect to a remote Apache Derby server. Derby server version is 10.13.1.1 (Debian Stretch), java version on remote system is openjdk 1.8.0_181.

Thanks to Lars Vogel, i’ve learned i have to run the derby server with -h 0.0.0.0 so to accept both local and remote connections. Connecting locally works fine.

Remote access (both with ij or tools like SquirrelSQL or LibreOffice Base) fails with a strange Java error:

NoSuchMethodError: java.nio.ByteBuffer.clear()Ljava/nio/ByteBuffer

Finally i found that it’s a matter of different derby versions. Client version of derby was 10.14.1.0. With version 10.13.1.1 on client, too, the error disappeared…

Java / jarsigner: Un-sign / re-sign jar files

Re-signing jar files is a pain if there are old signatures to remove. jarsigner happily would add the new signature, rendering the jar invalid if the old signatures are still present. There’s no command line switch to tell jarsigner to remove the old signatures first. So, one has to unpack each jar file first, remove the META-INF/*.SF and *.RSA files, and zip the jar again… NO! The linux version of zip comes with a nice command line option „-d“ to remove files from a zip. So, just execute the following command to remove any existing signatures from a jar file (thanks martinhans!):

zip -d file.jar 'META-INF/*.SF' 'META-INF/*.RSA'

To iterate over a whole bunch of jar files, just embed that command into a bash for loop:

for i in *.jar; do zip -d "$i" 'META-INF/*.SF' 'META-INF/*.RSA';done

In fact, you’re done 🙂

For re-signing mutiple jars: jarsigner is able to read the keystore / key password from a file or from an environment variable, using the -keypass / -storepass command line option together with the :file or the :env modifier.

So, it’s possible to put each of the passwords in a file and use a for loop like this to sign all jars in the current directory using the key key_alias:

for i in ./*.jar; do jarsigner -storepass:file ~/.storepass -keypass:file ~/.keypass "$i" key_alias;done

To make jarsigner read the passwords from an env variable, you’ll have to create those variables first:

„Fun“ with JavaWS and PAC (Proxy AutoConfig)

Using a *.pac / *.dat file for proxy auto-configuration is a very useful thing, especially in enterprise environments. Generally, JavaWS supports using PAC. But sadly, Oracle’s current JRE versions (7u71 / 7u72) refuse to use a PAC file that makes use of of JavaScript functions like dnsDomainIs(). Using such a PAC file will lead to errors like this:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot find function dnsResolve in object com.sun.deploy.net.proxy.SunAutoProxyHandler@e04204. (<Unknown source>#34) in <Unknown source> at line number 34

Caused by: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot find function dnsResolve in object com.sun.deploy.net.proxy.SunAutoProxyHandler@e04204. (<Unknown source>#34)

This looks like JDK-8038986 and JDK-6945158. So, it seems to be fixed in current version of OpenJDK, and hopefully, it gets fixed in Oracle’s JRE’s, too. In the meanwhile, the workaround found at JDK-6945158 worked for me, too: make sure that the PAC file returns anything without using dnsDomainIs(), for example using a Regex-based test like shExpMatch (thanks os!) or doing a simple string comparison like

if (host==“[hostname]“)
return „PROXY proxy_host:proxy_port“;

Some Java NG Plugin / Applet resources

Collection of some resources on the NG Java Plugin and new Applet features: