Creating ‘mini-caches’ in Java to speed up database calls.

Java has a cool construct called a Hashmap, this can be used to cache the result of a routine using a key.

For example.

Map cache=new HashMap();
public String getUnitsAtSite(String siteCode) {
     // is the sitecode already in the cache?
     if (cache.containsKey(siteCode)) return (String)cache.get(siteCode);
     String getSites=.... < get data from data base

     cache.put(siteCode,getSites);
     return getSites;

}

Now ofcourse there are downsides, if the data changes we won't see it - ofcourse we could do a cache.clear(); or cache.delete(key) on save of a change of record.
Advertisements

The WONDERFUL Apache Server

So, I had a liferay server running on a Virtual Server on tomcat, then my boss announces that he’s not buying another server and I have to run PHP on it as well.

Fantastic APACHE comes to the rescue. Using virtual hosts it is not only possible to run PHP on a server but also forward domains off to a liferay server.

Ok all you have to do (it really is this simple), is to modify the https.conf file and restart apache.

Here’s some examples

1. Redirect to an external server

<VirtualHost 12.34.56.78:80>
ServerName www.mydomainname.com
ProxyPass / http://www.theotherdomainname.co.uk/
ProxyPassReverse / http://www.theotherdomainname.co.uk/
</VirtualHost>

(note this is NOT a redirect in fact but proxying the remote server – so you keep the same domain name! great!) BUT note that you could get the same effect by changing the A record on the domain in the DNS! But this is a great shortcut for placeholding until I have something to put there.

Proxying to a liferay server

<VirtualHost 12.34.56.78:80>
ServerName www.liferayserver.com
ProxyPass / http://12.34.56.78:8080/
ProxyPassReverse / http://12.34.56.78:8080/
</VirtualHost>

And finally running a local PHP/Apache combination

<VirtualHost 12.34.56.78:80>
 ServerName www.myphpserver.com
 DocumentRoot /var/www/
</VirtualHost>

12.34.56.78 = the servers IP (don’t think I’d give out a real IP !)

Don’t forget to restart your APACHE server after doing the changes

/etc/init.d/apache2 restart

Starting a glassfish server on a VPS, solving Memory Problems.

1. Check your hosts file – if your glassfish server constantly says ports are occupied make sure

/etc/hosts

the localhost entries are first

2. Make sure your host is called localhost

hostname localhost

3. Solve memory problems

export _JAVA_OPTIONS=”-Xms20m -Xmx64m -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:NewSize=10m -XX:MaxNewSize=10m -XX:SurvivorRatio=6 -XX:TargetSurvivorRatio=80 -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled”


before you start your server.

Using threading to do processing. Improving the User Experience.

One great thing about Java is that it’s easy to create Threads. My UML diagrams are showing how I am now splitting processing away from the user interface.

Why make a user wait, when a background thread could be fired to do a calculation, produce a report and it’s not only users that can benefit from background processing. I have a comms routine which basically get’s a UDP message, puts it in a database and responds to the unit. Then, in the background, runs a thread that processes the data into the system. 

To create a thread is very easy. You can either use an EJB timer function to start a threaded routine, or create a class that extends a Thread, and then use new Thread(new yourClass()).start();

 

Finding out where I am without an external API.

My work is incredibly interesting. I do a LOT of mapping and location software, often it’s easy to plug in to something like Google Maps who provide their awesome API for programmers to hack. But sometimes this isn’t possible.

Of of my projects involves a world map with a plot of different devices locations. However in this case, as it was run in a back end query it would not be covered by any web api’s license. My own solution was needed. The first thing I did was to get some data, a cities table with 2.6 million entries is available free on the internet, and a countries table, I modified the cities table to include the country name.

Then I simply used a nested query on the cities table.

select * from cities where (lat>4.3142004 and lat<4.7142) 
and (cities.long>-74.0833 and cities.long<-73.683304) limit 1

This effectively is a box surrounding the point I’m looking for. Note that if the box fails to find anything I can just increase the parameters and rerun the query.

You can see that the figures form a box around the point I’m looking for, in this case I did not need the address, just what country it was in. (returned the whole record for testing).

Incidentally the cities table is pretty interesting, you wouldn’t believe how many London’s there are!

The cities file can be downloaded here

Primefaces Tree in a layout or panel doesn’t work

I must be losing more hair than anything. The tree function in a layout doesn’t work, although the backing bean is called the selectedItems array passed to it is empty. So here’s the fix.

Your code now looks like this probably (or something like it).

<p:panel style="height:80%">   <p:tree selection="#{indextree.selectedNodes}"
 update="Map" propagateSelectionUp="true" propagateSelectionDown="true"
 nodeSelectListener="#{indextree.onNodeSelect}" id="tree"
 style="font-size:12pt" selectionMode="checkbox" value="#{indextree.root}" var="node"> <p:treeNode> <h:outputText value="#{node}"/> </p:treeNode>
</p:tree>
</p:panel>

So simply create another xhtml file and put the tree in it on it’s own. In this case I called it treeTest.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core">
<f:view contentType="text/html"><h:head>
<title>Tracking</title>
</h:head>
<h:body style="font-size:8pt" >
<h:form id="boris" enctype="multipart/form-data">
<p:tree selection="#{indextree.selectedNodes}" update="Map" propagateSelectionUp="true" propagateSelectionDown="true" nodeSelectListener="#{indextree.onNodeSelect}" id="tree" style="font-size:12pt" selectionMode="checkbox" value="#{indextree.root}" var="node">
<p:treeNode>
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree></h:form></h:body>
</f:view>
 </html>

Now in your original file replace your tree code with an iframe! Tada, it all works! (note it should have < at the start and > at the end but wordpress goes a bit mad if I do that.

iframe src="treeTest.xhtml" style="height:80%;border-style:none;border-width:1px;" ></iframe

By the way this is fixed in the latest V3.0M

Now that’s clever.

OK,

So to upgrade my iPhone to IOS 5 I decided to go to the pub, have a nice meal and a pint of cider. Great idea you say. But, due to the cider I unplugged my  iPhone before it had finished syncing the apps. No problem, I thought I’ll just sync it in the morning. Some of the apps were missing some would not work when I touched them.

Morning comes, upgrade iPad…and guess what… all my apps are working, seems little iPhone synced itself with the cloud and fixed itself…scary wonderful technology.

Well done Apple. Steve would be proud because I know I am.

IOS 5 out NOW but…

 

I think their servers are suffering, 16 hours on a broad band line for the iPhone version 53 minutes though for the iPad version ….

Apple, you should have started the update WHILE THE USA WAS ASLEEP! silly.

Ok some of us have been sitting in iTunes and hitting Check for Update all day…

RIP Steve Jobs

I just wanted to pay tribute to Steve Jobs for his incredible contribution to IT on this Blog. I look forward to the future but Steve will be a sad loss to all of us who use Apple stuff and a few who don’t.

 

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.

 

Before you do any of the following make sure you are using the very latest MYSQL driver.

I have been hunting through the internet to find a solution to this one, after about 24 hours it seemed that the Glassfish 3 server could no longer find connections. The solution was actually in the error message (but you know how you never read ALL the way through a java error message).

The last packet successfully received from the server was 48,673,937 milliseconds ago. The last packet sent successfully
to the server was 48,673,937 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should
consider either expiring and/or testing connection validity before use in your application, increasing the server
configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at

Actually this is middy deceptive, because you need to set more than that.

I set in my sun-resources.xml file…

<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="10" connection-creation-retry-interval-in-seconds="1" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="30000" max-wait-time-in-millis="60000" name="mysql_sollatek_adminPool" non-transactional-connections="false" pool-resize-quantity="3" res-type="javax.sql.ConnectionPoolDataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
    <property name="User" value="admin"/>
    <property name="Password" value="xxxx"/>
    <property name="serverName" value="xxxx"/>
    <property name="portNumber" value="3306"/>
 <property name="autoReconnect" value="true"/>
 <property name="autoReconnectForPools" value="true"/>
    <property name="databaseName" value="xxxx"/>
    <property name="URL" value="jdbc:mysql://xxxx>
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
  </jdbc-connection-pool>

And in fact any where else you make a connection. Ensure that the auto reconnect is set to true. You could also set the number of retries in the reconnections to a higher property (default is 3).

Full details of these properties are usefully available here

Oh and a gotcha, don’t forget that if you have an app/jdbc resource on the server you need to add the properties to it in the jDBC connection pool and restart the server otherwise it won’t get there!

If none of that works, try making sure that the glass fish server only keeps the connections open for a shorter time than the mysql server.

In your connection pools…

Pool Settings
Initial and Minimum Pool Size:
Connections

Minimum and initial number of connections maintained in the pool
Maximum Pool Size:
Connections

Maximum number of connections that can be created to satisfy client requests
Pool Resize Quantity:
Connections

Number of connections to be removed when pool idle timeout expires
Idle Timeout:
Seconds

Maximum time that connection can remain idle in the pool
Max Wait Time:
Milliseconds

Amount of time caller waits before connection timeout is sent

If none of this works and you still have the problem (which is odd on one glass fish server this fixed it) then change the datasource from a connection pool driver to an XA datasource driver. 

Pool Name:
my connectionpoolname
Resource Type:
    javax.sql.DataSource  javax.sql.XADataSource  javax.sql.ConnectionPoolDataSource  java.sql.Driver 

Must be specified if the datasource class implements more than 1 of the interface.
Datasource Classname: