Oracle JDBC memory settings

Many applications use ancient versions of Oracle’s JDBC drivers, as they are downloaded manually and seldom upgraded. That is a pity as the newer drivers offer much better performance. However, some of the performance gains are bought with increased memory consumption and that can be a problem.

We ran into an issue with the connection pool in JBoss. It uses connections in round-robin, so as long as there is some load the pool tends to stay at peak size. Each connection normally keeps a buffer cache and it may cache other things as well. The size of the connections would grow over time, eventually consuming most of the heap.

A JBoss-specific workaround is to use the cli and close the idle connections (off-peak):


/subsystem=datasources/xa-data-source=DS/:flush-idle-connection-in-pool

DS is the name of the data source. A better approach may be to set the system property oracle.jdbc.useThreadLocalBufferCache to true. That moves the buffer cache from the connections to thread locals. Depending on how the application behaves that may be better as the memory is reclaimed when a thread dies. Plus a given thread may be more likely to issue the same SQL multiple times and can thus benefit more from the cache.

It may also be useful to limit the maximum buffer size with oracle.jdbc.maxCachedBufferSize. The implicit statement cache is normally off, but if it is enabled the size can be controlled using oracle.jdbc.implicitStatementCacheSize and oracle.jdbc.freeMemoryOnEnterImplicitCache can force buffers allocated for a statement to be released when it is put into the cache. In most cases it is best to leave those options alone.

See Oracle JDBC Memory Management for the whole story!

Categories: Java, Oracle, Performance

Microsoft finally got something right, bash on Windows!

I’m still on Windows 7. It was a great OS. It is becoming less great with nagging and spying upgrades from Microsoft, but it works well and I hated Windows 8. Windows 10 seems a bit better, but it is still inferior to Windows 7 in my view. Or was until now! Finally Microsoft seems to have found a killing feature: native bash on Windows, supported by Canonical (Ubuntu). Read more in this blog. Perhaps it is time to upgrade?

Categories: Windows

JBoss EAP6 JGroups MPING fails with invalid argument

What to do if JBoss EAP6 fails to discover other cluster members with the following error from JGroups?


[org.jgroups.protocols.MPING] failed sending discovery request:
  java.io.IOException: Invalid argument
  at java.net.PlainDatagramSocketImpl.send(Native Method)
  at java.net.DatagramSocket.send(DatagramSocket.java:693)
  at org.jgroups.protocols.MPING.sendMcastDiscoveryRequest(MPING.java:300)

In my case the solution was simple. Add -Djava.net.preferIPv4Stack=true to jbossctl.sh. Apparently the multicast code doesn’t work with IPv6 on my Linux version.

Categories: Java, Networking

Beware of OpenJPA when upgrading Java

People often ask me if we should upgrade to the latest Java version and I always answer the same thing. Of course we should, what could be wrong about better performance and the latest security updates? I always amend something about trying it in a test environment first, though. Over the years I have seldom seen any problems with a Java SE update, the platform is remarkably backwards compatible. But then magic entered the stage.

The magic in this case is the build time byte code enhancement performed by OpenJPA. Apparently the byte code verifier was changed a bit in Java SE 7, so the classes are no longer valid. Oracle’s JVM complains. IBM’s Java 7 implementation crashes spectacularly. With Java 6 it just works.

Crash with IBM Java 7

OpenJPA has always been my least favourite JPA implementation and this did nothing to change that. Oh, they have fixed the byte code enhancer in newer versions (but if you are stuck with an old application server that might not help), but a similar problem exists for Java SE 8 and who wants to bet on everything playing out with Java 9 and 10? Not me.

It also says something about IBM’s JDK. It really shouldn’t crash on an invalid class, simply reject it and move on.

Nevertheless, my recommendation is still to use the latest Java version, but again – test it first and if you are using OpenJPA and/or anything but Oracle’s mainstream JVM, test it well!

Categories: Java

Handle UnauthorizedSessionRequestException on WAS 8.5.5

WebSphere 8.5.5 normally uses LTPA tokens for authentication and session cookies for tracking HTTP sessions. The two are not connected and they interact in a sometimes very frustrating way. The HTTP session expires when the user has been inactive (i.e. no requests have been received by the server) for a given time. The LTPA token on the other hand has a fixed expiration time regardless of user activity. This means that a user can be logged out while active and while still having a session. Furthermore it is tricky to handle this as any attempt to access the session for a logged out user fails with an UnauthorizedSessionRequestException, complaining that an anonymous user has attempted to access a session owned by someone else. What to do?

There is a configuration option described here and here that makes the session manager invalidate the session and return null instead. This works well as that is what web applications normally do when a user has been logged out, so it plays nicely with other security frameworks.

To enable the option pick Servers-Server Types-WebSphere application servers-servier name-Session management, find Additional Properties and select Custom Properties, then set InvalidateOnUnauthorizedSessionRequestException=true. Save the changes and restart the server. The UnauthorizedSessionRequestException is history!

Categories: Java

Encrypt ZFS drives on FreeNAS 0.7.2 (FreeBSD 7)

We recently had a break-in and found out about it when we were far from home. I worried about many things, among them the unencrypted files on my home NAS. Not that I have any state secrets buried, but the thought of having private e-mails, photos and so on in the hands of criminals just felt wrong. Fortunately the thieves left my computers, so I decided to do something about it.

I have an old NAS with FreeBSD 0.7.2 (no longer available) running FreeBSD 7. It does support encryption, albeit a bit manually. First I had to create a geli encryption key on the USB boot device:


umount /cf
mount -o rw /dev/da0a /cf
mkdir /cf/boot/keys
dd if=/dev/random of=/cf/boot/keys/nas.key bs=128k count=1

Next I destroyed the partition on the first disk to go and configured it for encryption with geli:


dd if=/dev/zero of=/dev/ad10 bs=512 count=10
geli init -b -K /cf/boot/keys/nas.key -s 4096 -l 256 /dev/ad10
geli attach -k /cf/boot/keys/nas.key /dev/ad10

Repeat with other drives (ad8 in this case) and create a mirror:


zpool create -m none nas-pool1 mirror /dev/ad10.eli /dev/ad8.eli

Next edit /cf/boot/loader.conf to enter the passphrases at boot time:


geli_ad8_keyfile0_load="YES"
geli_ad8_keyfile0_type="ad8:geli_keyfile0"
geli_ad8_keyfile0_name="/boot/keys/nas.key"
geli_ad10_keyfile0_load="YES"
geli_ad10_keyfile0_type="ad10:geli_keyfile0"
geli_ad10_keyfile0_name="/boot/keys/nas.key"

Reboot and make sure it works, then add additional drives and resilver. Peace of mind restored!

Categories: FreeNAS

Timeouts for Oracle XA datasources in JBoss EAP 6

The documentation for configuring datasources in JBoss EAP 6 is somewhat lacking when it comes to timeouts. Normally this is fine, but what if there are network issues? With the wrong timeout settings the application can hang until it is killed and restarted. With proper timeouts it can handle an outage and recover.

Here is an example:


<xa-datasource jndi-name="java:/AppDS" pool-name="AppDS">
  <xa-datasource-property name="URL">
    ${appdb.url}
  </xa-datasource-property>
  <xa-datasource-property name="nativeXA">true</xa-datasource-property>
  <xa-datasource-property name="ConnectionProperties">
    oracle.jdbc.ReadTimeout=330000
  </xa-datasource-property>
  <xa-datasource-class>
    oracle.jdbc.xa.client.OracleXADataSource
  </xa-datasource-class>
  <driver>oracle</driver>
  <security>
    <user-name>${appdb.user}</user-name>
    <password>${appdb.password}</password>
  </security>
  <xa-pool>
    <min-pool-size>${appdb.min.pool.size}</min-pool-size>
    <max-pool-size>${appdb.max.pool.size}</max-pool-size>
    <prefill>false</prefill>
    <use-strict-min>false</use-strict-min>
    <flush-strategy>FailingConnectionOnly</flush-strategy>
    <is-same-rm-override>false</is-same-rm-override>
    <no-tx-separate-pools/>
    <pad-xid>true</pad-xid>
    <wrap-xa-resource>true</wrap-xa-resource>
  </xa-pool>
  <validation>
    <valid-connection-checker class-name=
      "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>
    <stale-connection-checker class-name=
      "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>
    <exception-sorter class-name=
      "org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>
  </validation>
  <timeout>
    <blocking-timeout-millis>60000</blocking-timeout-millis>
    <xa-resource-timeout>310</xa-resource-timeout>
    <query-timeout>300</query-timeout>
    <set-tx-query-timeout/>
  </timeout>
  <statement>
    <track-statements>false</track-statements>
  </statement>
  <recovery no-recovery="false">
    <recover-credential>
      <user-name>${appdb.user}</user-name>
      <password>${appdb.password}</password>
    </recover-credential>
  </recovery>
</xa-datasource>

The oracle.jdbc.ReadTimeout is essential. It sets the network timeout on the socket, making reads time out eventually in the face of a broken connection. The default TCP timeout for established connections is very long, so it is important to set a value. It should be larger than the transaction timeouts. The query timeout and tx-query-timeout both limit the time that individual statements can take. The query timeout is used when there is no transaction, otherwise the remaining time until transaction timeout is used.

Note that read timeout is in milliseconds, query timeout is in seconds.

Categories: Java, Networking, Oracle
Follow

Get every new post delivered to your Inbox.