Wednesday, December 28, 2011

Using Glassfish built-in connection pool (rather than dbcp or c3p0)

From http://skytteren.blogspot.com/2009/06/using-mysql-connection-pool-in.html


Using MySQL connection pool in Glassfish V3
I tried with a simple data source in Spring, but it isn't meant for production environments. So I wanted to move from:

<bean id="simpleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/database"/>
<property name="username" value="database"/>
<property name="password" value="s3cr3t"/>
</bean>

to:

<bean id="jndiDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/databasePool" />
</bean>

This can be done from within Glassfish admin, by creating the connection pool with the specified jndi name.

c3p0 connection pool in broadleafdemo (instead of dbcp)

Why c3p0 ?
The old dbcp (1.2.2 is used in broadleafdemo) is less robust than c3p0.
http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0
Will do some performance testing with dbcp 1.4.

1. Open broadleafdemo.war\WEB-INF\applicationContext-demo.xml
2. Modify your webDS and webStorageDS beans 
2a. change the class to com.mchange.v2.c3p0.ComboPooledDataSource
2b. change property name to driverClass (from driverClassName)
2c. change property name to jdbcUrl (from url)
2d. change property name to user (from username)

<bean id="webDS" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/broadleaf" />
<property name="user" value="user" />
<property name="password" value="password" />
</bean>
    <bean id="webStorageDS" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="org.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/broadleaf" />
<property name="user" value="user" />
<property name="password" value="password" />
</bean>

3. Download c3p0 from http://sourceforge.net/projects/c3p0/files/latest/download , extract, and copy c3p0-xxxx.jar (c3p0-0.9.1.2.jar at the time of this writing) into broadleafdemo.war\WEB-INF\lib

4. (Optional) You can also remove commons-dbcp.jar from broadleafdemo.war\WEB-INF\lib as it's no longer used.

References:
http://stackoverflow.com/questions/3002899/spring-configuration-of-c3p0-with-hibernate
http://stackoverflow.com/questions/520585/connection-pooling-options-with-jdbc-dbcp-vs-c3p0
http://sourceforge.net/projects/c3p0/

Monday, December 26, 2011

Running CLUSTERED Broadleaf Ecommerce 1.5.0 Demo in Oracle GlassFish Server 3.1.1

Once you have Broadleafdemo running in Oracle Glassfish 3.1.1 (read http://lydonchandra.blogspot.com/2011/12/running-broadleaf-ecommerce-150-demo-in_26.html), you might want to run it in a clustered Glassfish configuration using Apache 2.2 + mod_jk connector.

Most of the instructions below are obtained from http://tiainen.sertik.net/2011/03/load-balancing-with-glassfish-31-and.html
1. From Glassfish admin, create a new cluster, say cluster1

2. Once cluster1 is created, go to Instances tab, and create 2 new instances, instance1 and instance2

3. Create mod_jk listener, go to Configurations > Network Config > Network Listener , and click on New.
3a. Enter "mod-jk" on Name textbox,
3b. enter 28009 as port number and
3c. make sure you check the JK Listener checkbox. Click Save.
3d. Stop and start the cluster

4. Download Apache 2.2 and mod_jk (http://tomcat.apache.org/download-connectors.cgi), extract Apache 2.2 and mod_jk.so into Apache22/modules directory

5. Add the following to Apache httpd.conf


Include conf/mod-jk.conf


6. create conf/mod-jk.conf

LoadModule jk_module modules/mod_jk.so
 
# Where to find workers.properties
JkWorkersFile conf/workers.properties

# Where to put jk logs
JkLogFile logs/mod_jk1.log
 
# Set the jk log level [debug/error/info]
JkLogLevel info 
 
# Select the log format
JkLogStampFormat  "[%a %b %d %H:%M:%S %Y]"
 
# JkOptions indicates to send SSK KEY SIZE
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
 
# JkRequestLogFormat
JkRequestLogFormat "%w %V %T"
               
# Mount your applications
JkMountFile conf/uriworkermap.properties               

# Add shared memory.
# This directive is present with 1.2.10 and
# later versions of mod_jk, and is needed for
# for load balancing to work properly
JkShmFile logs/jk.shm 
              
# Add jkstatus for managing runtime data
    JkMount status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1



7. Create worker.properties with the following information, put the correct ip address on worker.node1.host

worker.node1.port=28009
worker.node1.host=127.0.0.1
worker.node1.type=ajp13
worker.node1.lbfactor=1
worker.status.type=status
worker.loadbalancer.sticky_session=1
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=node1
worker.list=loadbalancer,status

8. Create uriworkermap.properties to tell mod_jk which webapp to mount

/=loadbalancer
/*=loadbalancer
/broadleafdemo=loadbalancer
/broadleafdemo/*=loadbalancer

9. Start httpd

Running Broadleaf Ecommerce 1.5.0 Demo in Oracle GlassFish Server 3.1.1

Once you got it deployed and running in JBoss 7 (read my previous post http://lydonchandra.blogspot.com/2011/12/running-broadleaf-ecommerce-150-demo-in.html)

you can just use the same broadleafdemo.war (which has modified compass JAR) and

deploy it as an Web-Application from the GlassFish Server administration page > Applications > Deploy



Sunday, December 25, 2011

Running Broadleaf Ecommerce 1.5.0 Demo in JBoss 7.1.0.CR1b

A bit more complicated as it should be in the beginning, where JBoss changes the protocol name from vfszip to vfs,

1. so I had to build the latest Compass trunk (rev 3940) from http://svn.compass-project.org/svn/compass/trunk/

2. Modify http://svn.compass-project.org/svn/compass/trunk/src/main/src/org/compass/core/config/binding/scanner/ScannerFactoy.java
to:

else if ( url.getProtocol().equals("vfszip") || 
url.getProtocol().equals("vfs") ) {
            url = new URL(urlString);
            return new JarScanner(basePackage, url.openStream(), filter);
        }

3. Replaced the broadleaf's supplied compass-2.2.0.jar with the newly built Compass jar file ( available from http://www.multiupload.com/AY0F7UPKX6 as of Dec 25 2011)

4. Start JBoss (in standalone mode), everything should work fine!!




/*
 * Copyright 2004-2009 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.compass.core.config.binding.scanner;

import java.io.File;
import java.io.IOException;
import java.net.URL;

/**
 * @author kimchy
 */
public class ScannerFactoy {

    public static Scanner create(String basePackage, URL url, Filter filter) throws IOException {
        String urlString = url.toString();
        urlString = urlString.substring(0, urlString.lastIndexOf(basePackage));
        if (urlString.endsWith("!/")) {
            urlString = urlString.substring(4);
            urlString = urlString.substring(0, urlString.length() - 2);
            url = new URL(urlString);
        }


        if (!urlString.endsWith("/")) {
            return new JarScanner(basePackage, url.openStream(), filter);
        } else if (url.getProtocol().equals("file")) {
            File f = new File(url.getPath());
            if (f.isDirectory()) {
                return new FileScanner(basePackage, f, filter);
            } else {
                return new JarScanner(basePackage, url.openStream(), filter);
            }
        } else if ( url.getProtocol().equals("vfszip") || 
url.getProtocol().equals("vfs") ) {
            url = new URL(urlString);
            return new JarScanner(basePackage, url.openStream(), filter);
        } else {
            throw new IOException("Protocol [" + url.getProtocol() + "] is not supported by scanner");
        }
    }
}

Running Broadleaf eCommerce Demo 1.5.0 in JBoss 5.1

I had problems deploying Broadleaf eCommerce Demo 1.5.0 in JBoss 7.0. So I went back to JBoss 5.1 and followed this forum post and finally got the broadleafdemo.war to deploy in JBoss 5.1.

Why JBoss you ask ? Well some enterprise users use JBoss and we want to give them an easier option to deploy inside their JBoss app server, rather asking them to install Tomcat or run from Jetty.
If they have to install Tomcat or run from Jetty, then they will have to configure their network security settings etc etc, it's just not fun. So why JBoss again ? To make deployment easier, for now at least :)

Steps:
1. Download and extract JBoss 5.1 if you haven't already, and make sure you can run broadleaf with mysql as your database (follow my previous post about running broadleaf with mysql or google it).
2. Remove jboss-5.1.0.CR\common\lib\hibernate-validator.jar (or move it somewhere else)
3. Copy the expanded broadleafdemo.war to jboss-5.1.0.CR\server\default\deploy
4. Download compass-2.3.1-beta1.jar from either java2s.com or rutgersmaps and replace broadleafdemo.war\WEB-INF\lib\compass-2.2.0.jar
5. Start JBoss, and you should be able to access http://myserver:8080/broadleafdemo

Saturday, December 24, 2011

Running Broadleaf E-commerce demo in Various Java Application Server and Database

First we start using MySQL and Tomcat 7.0

1. Extract broadleafdemo.war file into an expanded war
2. As detailed here in http://www.broadleafcommerce.org/forum/viewtopic.php?f=9&t=379



2a. in META-INF/persistence-demo.xml' file replace 
- org.hibernate.dialect.HSQLDialect by org.hibernate.dialect.MySQLDialect in the 'blPU' and 'blSecurePU' persistence unit configurations

2b. in WEB-INF/applicationContext-demo.xml' file replace the following lines 


<bean id="webDS" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
      <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
      <property name="url" value="jdbc:hsqldb:mem:broadleaf;ifexists=false" />
      <property name="username" value="sa" />
      <property name="password" value="" />
   </bean>


with


<bean id="webDS" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">

      <!-- The JDBC Driver class name. -->
      <property name="driverClassName" value="com.mysql.jdbc.Driver" />
      <property name="url" value="jdbc:mysql://localhost:3306/broadleaf" />
      <property name="username" value="MY_USER_NAME" />
     <property name="password" value="MY_PASSWORD" />
   </bean>






and update the username and password properties accordingly!!!


3. login to mysql and create database 'broadleaf'


mysql>> create database broadleaf;


4. copy the expanded broadleaf.war directory created in #1 above into Tomcat 7.0 directory


5. download & copy mysql-connector-java-5.1.17.jar into broadleafdemo.war/WEB-INF/lib


6. start tomcat.




Caveat:


For some reason Spring Framework complains about NOT finding the com.mysql.jdbc.Driver ?
However the broadleafdemo site works OK.



[ INFO] 07:56:49 SchemaExport - exporting generated schema to database
Cannot load JDBC driver class 'org.mysql.jdbc.Driver'
java.lang.ClassNotFoundException: org.mysql.jdbc.Driver
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoa
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoa
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSou
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource
        at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.get
ataSourceConnectionProvider.java:71)






Monday, December 19, 2011

Reading big file quickly by skipping

This is to read a grid file with columns such as
a1 b1 c1
a2 b2 c2
a3 b3 c3
a4 b4 c4
a5 b5 c5
a6 b6 c6
a7 b7 c7
a8 b8 c8
a9 b9 c9
a10 b10 c10


say we want to read 'approximately' every 4 lines, i.e. line2 then line6 and then line10, then what we can do is
to jump using the file offset. As we only want to read a 'whole' line and we can't guarantee  whether a line is 'whole' or not if we use the file offset, we read and then discard a line, and read the next one. This assumes a line is separated by newline.


read line and discard
read line and save //a2 b2 c2
jump 27bytes ahead //a line is approx 9bytes with a newline
read line and discard
read line and save //a6 b6 c6
jump 27bytes ahead
read line and discard
read line and save //a10 b10 c10
...


     using boost::iostreams::position_to_offset;
     using boost::iostreams::seek;
     using boost::iostreams::stream_offset;

     stream_offset off;

         // save EOF offset so we know if we have finished reading the file
     stream_offset endoff = position_to_offset(seek(in, 0, BOOST_IOS::end));
     // go back to beginning of file, we have gone to EOF in line above
     seek(in, 0, BOOST_IOS::beg);
     string line2;
     while( true ) {
                 // first read, we get "incomplete line", so ignore it
         getline(in, line2);

                 // second read, we get "complete" line
         getline(in, line2);
         //cout << line2 << endl;

                 // jump approximately 1000 lines ahead
         off = position_to_offset(seek(in, 200000, BOOST_IOS::cur));

                 // finish reading the file
         if( off > endoff ) {
             break;
         }
     }

     cout << "finished" << endl;

Sunday, December 18, 2011

Java Object Size

To get the object size, YourKit Profiler v9.0.2 is used and for SimpleClass, shallow sizes are used.

public class SimpleClass {
public int x;
}
For 32bit Java, the size of the object is 16 bytes.
For 64bit Java, size is 24 bytes

public class SimpleClass {
public int x;
public int y;
}
32bit Java -> 16 bytes.
64bit Java -> 24bytes.

public class SimpleClass {
public int x;
public int y;
public int z;
}
32bit Java -> 24 bytes.
64bit Java -> 32 bytes.

http://javaquirks.blogspot.com/2008/03/it-gets-worse.html

______32-bit 64-bit
Object 8 16
Integer 16 24
Long 16 24
Float 16 24
Double 16 24
String 40 64
Date 24 32
Calendar 432 544
byte[0] 16 24
byte[32] 48 56
byte[128][0] 2576 4120
ArrayList(1) 56 96
ArrayList(2) 80 128

Thursday, December 15, 2011

Profiling geoserver 2.1.2 using YourKit Java Profiler 9

[Load Testing Geoserver]

[background]

- Load testing is done using Apache JMeter 2.5.1 r1177103

- A text file with the url (including random bbox, not scaled) is loaded by JMeter

- YourKit Java Profiler 9 is used to profile geoserver

- An image file 4.5GB in size is served.

- The urls are generated using the following python script:

import random
#http://10.1.1.2:8080/geoserver/don/wms?service=WMS&version=1.1.0&request=GetMap&layers=don:china&styles=&bbox=73.115,19.934,135.103,53.597&width=607&height=330&srs=EPSG:4326&format=image/png
minx = 73.115
miny = 19.934
maxx = 78.103
maxy = 23.597
thefile = open('geoload2.txt', 'w')
wms1 = 'geoserver/don/wms?service=WMS&version=1.1.0&request=GetMap&layers=don:china&styles=&width=800&height=600&srs=EPSG:4326&format=image/png&bbox='
distancex = maxx - minx
distancey = maxy - miny
for n in range(1000):
minx1 = minx + random.random() * distancex
miny1 = miny + random.random() * distancey
thefile.write( wms1 + str(minx1) + ',' + str(miny1) + ',' + str(maxx) + ',' + str(maxy) + '\n' );

[load-testing-shape-file]
Serving up a 150MB shape file as WMS,
The throughput is about 2.2 per second



Stack trace of one of the hotspot org.geotools.index.quadtree.LazySearchIterator.hasNext() which is called 50% of the time,
can be seen in the appendix section below.

[to-do]
1. Reduce the number of filters and see if it performs better.
-> no it doesn't improve throughput in measurable amount. will check if cpu usage is significantly less.



[appendix]
"Name","Time (ms)","Invocation Count"
"org.geotools.index.quadtree.LazySearchIterator.hasNext()","287819","76580"
"org.geotools.data.shapefile.indexed.IndexedShapefileDataStore.getAttributesReader(boolean, boolean, Query, SimpleFeatureType)","286712","57"
"org.geotools.data.shapefile.indexed.IndexedShapefileDataStore.getFeatureReader(String, Query)","",""
"org.geotools.data.AbstractDataStore.getFeatureReader(Query, Transaction)","",""
"org.geotools.data.DefaultFeatureResults.reader()","",""
"org.geotools.data.store.DataFeatureCollection.openIterator()","",""
"org.geotools.data.store.DataFeatureCollection.iterator()","",""
"org.geotools.data.store.DataFeatureCollection.features()","",""
"org.geotools.data.store.DataFeatureCollection.features()","",""
"org.geotools.data.crs.ForceCoordinateSystemFeatureResults.openIterator()","",""
"org.geotools.feature.collection.AbstractFeatureCollection.iterator()","",""
"org.geotools.renderer.lite.StreamingRenderer.drawPlain(Graphics2D, MapLayer, AffineTransform, CoordinateReferenceSystem, String, Collection, FeatureCollection, NumberRange, ArrayList)","",""
"org.geotools.renderer.lite.StreamingRenderer.processStylers(Graphics2D, MapLayer, AffineTransform, CoordinateReferenceSystem, Envelope, Rectangle, String)","",""
"org.geotools.renderer.lite.StreamingRenderer.paint(Graphics2D, Rectangle, ReferencedEnvelope, AffineTransform)","",""
"org.geotools.data.shapefile.indexed.IndexedShapefileAttributeReader.hasNext()","1044","38269"
"org.geotools.data.FIDFeatureReader.hasNext()","",""
"org.geotools.data.FilteringFeatureReader.hasNext()","",""
"org.geotools.feature.FeatureReaderIterator.hasNext()","",""
"org.geotools.feature.collection.DelegateFeatureIterator.hasNext()","",""
"org.geotools.data.crs.ForceCoordinateSystemIterator.hasNext()","",""
"org.geotools.renderer.lite.StreamingRenderer.drawPlain(Graphics2D, MapLayer, AffineTransform, CoordinateReferenceSystem, String, Collection, FeatureCollection, NumberRange, ArrayList)","",""
"org.geotools.renderer.lite.StreamingRenderer.processStylers(Graphics2D, MapLayer, AffineTransform, CoordinateReferenceSystem, Envelope, Rectangle, String)","",""
"org.geotools.renderer.lite.StreamingRenderer.paint(Graphics2D, Rectangle, ReferencedEnvelope, AffineTransform)","",""
"org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(WMSMapContext, boolean)","",""
"org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(WMSMapContext)","",""
"org.geoserver.wms.map.RenderedImageMapOutputFormat.produceMap(WMSMapContext)","",""
"org.geoserver.wms.GetMap.run(GetMapRequest, WMSMapContext)","",""
"org.geoserver.wms.GetMap.run(GetMapRequest)","",""
"org.geoserver.wms.DefaultWebMapService.getMap(GetMapRequest)","",""
"java.lang.reflect.Method.invoke(Object, Object[])","",""
"org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[])","",""
"org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint()","",""
"org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()","",""
"org.geoserver.gwc.wms.CacheSeedingWebMapService.invoke(MethodInvocation)","",""
"org.geoserver.gwc.wms.CacheSeedingWebMapService.invoke(MethodInvocation)","",""
"org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()","",""
"org.geoserver.gwc.wms.CachingWebMapService.invoke(MethodInvocation)","",""
"org.geoserver.gwc.wms.CachingWebMapService.invoke(MethodInvocation)","",""
"org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()","",""
"org.geoserver.ows.util.RequestObjectLogger.invoke(MethodInvocation)","",""
"org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()","",""
"org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Object, Method, Object[])","",""
"java.lang.reflect.Method.invoke(Object, Object[])","",""
"org.geoserver.ows.Dispatcher.execute(Request, Operation)","",""
"org.geoserver.ows.Dispatcher.handleRequestInternal(HttpServletRequest, HttpServletResponse)","",""
"org.springframework.web.servlet.mvc.AbstractController.handleRequest(HttpServletRequest, HttpServletResponse)","",""
"org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(HttpServletRequest, HttpServletResponse, Object)","",""
"org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)","",""
"org.springframework.web.servlet.DispatcherServlet.doService(HttpServletRequest, HttpServletResponse)","",""
"org.springframework.web.servlet.FrameworkServlet.processRequest(HttpServletRequest, HttpServletResponse)","",""
"org.springframework.web.servlet.FrameworkServlet.doGet(HttpServletRequest, HttpServletResponse)","",""
"javax.servlet.http.HttpServlet.service(ServletRequest, ServletResponse)","",""
"org.mortbay.jetty.servlet.ServletHolder.handle(ServletRequest, ServletResponse)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.geoserver.filters.ThreadLocalsCleanupFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.geoserver.filters.SpringDelegatingFilter$Chain.doFilter(ServletRequest, ServletResponse)","",""
"org.geoserver.filters.SpringDelegatingFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.geoserver.platform.AdvancedDispatchFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.vfny.geoserver.filters.SetCharacterEncodingFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse)","",""
"org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterInvocation)","",""
"org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse)","",""
"org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(HttpServletRequest, HttpServletResponse, FilterChain)","",""
"org.springframework.security.ui.SpringSecurityFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse)","",""
"org.springframework.security.providers.anonymous.AnonymousProcessingFilter.doFilterHttp(HttpServletRequest, HttpServletResponse, FilterChain)","",""
"org.springframework.security.ui.SpringSecurityFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse)","",""
"org.springframework.security.ui.basicauth.BasicProcessingFilter.doFilterHttp(HttpServletRequest, HttpServletResponse, FilterChain)","",""
"org.springframework.security.ui.SpringSecurityFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse)","",""
"org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpServletRequest, HttpServletResponse, FilterChain)","",""
"org.springframework.security.ui.SpringSecurityFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(ServletRequest, ServletResponse)","",""
"org.springframework.security.util.FilterChainProxy.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.springframework.security.util.FilterToBeanProxy.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.geoserver.filters.LoggingFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.geoserver.filters.ReverseProxyFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"ch.lydon.TestFilter.TestFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.geoserver.filters.GZIPFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.geoserver.filters.SessionDebugFilter.doFilter(ServletRequest, ServletResponse, FilterChain)","",""
"org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletRequest, ServletResponse)","",""
"org.mortbay.jetty.servlet.ServletHandler.handle(String, HttpServletRequest, HttpServletResponse, int)","",""
"org.mortbay.jetty.security.SecurityHandler.handle(String, HttpServletRequest, HttpServletResponse, int)","",""
"org.mortbay.jetty.servlet.SessionHandler.handle(String, HttpServletRequest, HttpServletResponse, int)","",""
"org.mortbay.jetty.handler.ContextHandler.handle(String, HttpServletRequest, HttpServletResponse, int)","",""
"org.mortbay.jetty.webapp.WebAppContext.handle(String, HttpServletRequest, HttpServletResponse, int)","",""
"org.mortbay.jetty.handler.ContextHandlerCollection.handle(String, HttpServletRequest, HttpServletResponse, int)","",""
"org.mortbay.jetty.handler.HandlerCollection.handle(String, HttpServletRequest, HttpServletResponse, int)","",""
"org.mortbay.jetty.handler.HandlerWrapper.handle(String, HttpServletRequest, HttpServletResponse, int)","",""
"org.mortbay.jetty.Server.handle(HttpConnection)","",""
"org.mortbay.jetty.HttpConnection.handleRequest()","",""
"org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete()","",""
"org.mortbay.jetty.HttpParser.parseNext()","",""
"org.mortbay.jetty.HttpParser.parseAvailable()","",""
"org.mortbay.jetty.HttpConnection.handle()","",""
"org.mortbay.io.nio.SelectChannelEndPoint.run()","",""
"org.mortbay.thread.BoundedThreadPool$PoolThread.run()","",""
"org.geotools.index.quadtree.LazySearchIterator.next()","62","38254"

Monday, December 5, 2011

Set Authorization header in Apache 2.2

RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{QUERY_STRING} ^tocwidget=true&service=CSW&version=2.0.2&elementSetName=full&outputSchema=EBRIM&request=GetRecordById&id=(.*)$

RequestHeader set Authorization "Basic xxxxxxxxxxx"
RewriteRule ^/erdas-apollo/catalog/csw(.*)$ /erdas-apollo/catalog/csw?%{QUERY_STRING} [R,L]


To use environment variable:

RewriteCond %{REQUEST_METHOD} POST

RewriteCond %{QUERY_STRING} ^tocwidget=true&service=CSW&version=2.0.2&elementSetName=full&outputSchema=EBRIM&request=GetRecordById&id=(.*)$

SetEnvIfNoCase Request_URI "/erdas-apollo/catalog/csw" havedon

RequestHeader set Authorization "Basic xxxxxxxx" env=havedon

RewriteRule ^/erdas-apollo/catalog/csw(.*)$ /erdas-apollo/catalog/csw?%{QUERY_STRING} [R,L]

Thursday, November 24, 2011

CakePHP 2.0.2 problem PHPUnit 3.6

Fix is in 2.0.3 https://github.com/cakephp/cakephp/commit/bfd95d0e04235396b5011b790042765da856d4ea#diff-2

For now, all we need to do is to replace /lib/Cake/Test and /lib/Cake/TestSuite with the ones from CakePHP 2.0.3

Wednesday, September 21, 2011

Adding Indonesian Locale to Java web-app

Due to this bug
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6457127

you must have resources_in.properties
(not resources_id.properties) for the translation to work.

Indonesian code is in_ID and due to the bug above
"The indonesian locale gets parsed from both the identifiers "id" and "in". ISO 639 specifies only "id" as correct. When you ask the locale customer for its representation, it returns "in", which is not correct."

Wednesday, September 7, 2011

When will Java JIT start compiling into native code ?

With this following code, and

java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)

The main method will be compiled into native code when count is greater or equal to 170,000 (more or less, i didn't try to get a more accurate result)

>> jdk1.7.0/bin/java -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly t5

public class t5 {

public static void main(String[] args) {

int count = 170000;
int sum = 3;
int A = 4;
int B = 5;
for(int i=0; i sum += A + B;
}
}
}


Native code printed:

Code:
[Disassembling for mach='i386']
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} 'main' '([Ljava/lang/String;)V' in 't5'
0x02ccd480: mov %eax,0xffffd000(%esp)
0x02ccd487: push %ebp
0x02ccd488: sub $0x28,%esp ;*ldc ; - t5::main@0 (line 6)
0x02ccd48b: mov $0x0,%esi
0x02ccd490: mov $0x5,%edi
0x02ccd495: mov $0x4,%ebx
0x02ccd49a: mov $0x3,%eax
0x02ccd49f: mov $0x29810,%edx
0x02ccd4a4: jmp 0x02ccd4bb ;*iload
; - t5::main@13 (line 10)
0x02ccd4a9: xchg %ax,%ax
0x02ccd4ac: mov %ebx,%ecx
0x02ccd4ae: add %edi,%ecx
0x02ccd4b0: add %eax,%ecx
0x02ccd4b2: inc %esi ; OopMap{off=51}
;*goto
; - t5::main@29 (line 10)
0x02ccd4b3: test %eax,0x1c0100 ; {poll}
0x02ccd4b9: mov %ecx,%eax ;*goto
; - t5::main@29 (line 10)
0x02ccd4bb: cmp %edx,%esi
0x02ccd4bd: jl 0x02ccd4ac ;*if_icmpge
; - t5::main@16 (line 10)
0x02ccd4bf: add $0x28,%esp
0x02ccd4c2: pop %ebp
0x02ccd4c3: test %eax,0x1c0100 ; {poll_return}
0x02ccd4c9: ret ;*return
; - t5::main@32 (line 16)
0x02ccd4ca: mov %eax,0xffffd000(%esp)
0x02ccd4d1: push %ebp
0x02ccd4d2: sub $0x28,%esp
0x02ccd4d5: mov 0x10(%ecx),%esi
0x02ccd4d8: mov 0xc(%ecx),%edi
0x02ccd4db: mov 0x8(%ecx),%ebx
0x02ccd4de: mov 0x4(%ecx),%eax
0x02ccd4e1: mov (%ecx),%edx
0x02ccd4e3: mov %ecx,(%esp)
0x02ccd4e6: mov %esi,0x20(%esp)
0x02ccd4ea: mov %edi,0x1c(%esp)
0x02ccd4ee: mov %ebx,0x18(%esp)
0x02ccd4f2: mov %eax,0x14(%esp)
0x02ccd4f6: mov %edx,0x10(%esp)
0x02ccd4fa: call 0x636aad50 ; {runtime_call}
0x02ccd4ff: mov 0x10(%esp),%edx
0x02ccd503: mov %edx,%esi
0x02ccd505: mov 0x14(%esp),%eax
0x02ccd509: mov %eax,%edi
0x02ccd50b: mov 0x18(%esp),%ebx
0x02ccd50f: mov 0x1c(%esp),%eax
0x02ccd513: mov 0x20(%esp),%edx
0x02ccd517: jmp 0x02ccd4bb
0x02ccd519: nop
0x02ccd51a: nop
0x02ccd51b: mov %fs:0x0,%esi
0x02ccd523: mov 0xfffffff4(%esi),%esi
0x02ccd526: mov 0x184(%esi),%eax
0x02ccd52c: movl $0x0,0x184(%esi)
0x02ccd536: movl $0x0,0x188(%esi)
0x02ccd540: add $0x28,%esp
0x02ccd543: pop %ebp
0x02ccd544: jmp 0x02c9ba40 ; {runtime_call}
0x02ccd549: hlt
0x02ccd54a: hlt
0x02ccd54b: hlt
0x02ccd54c: hlt
0x02ccd54d: hlt
0x02ccd54e: hlt
0x02ccd54f: hlt
[Exception Handler]
[Stub Code]
0x02ccd550: call 0x02ccbb80 ; {no_reloc}
0x02ccd555: push $0x638dcd40 ; {external_word}
0x02ccd55a: call 0x02ccd55f
0x02ccd55f: pusha
0x02ccd560: call 0x637cf5f0 ; {runtime_call}
0x02ccd565: hlt
[Deopt Handler Code]
0x02ccd566: push $0x2ccd566 ; {section_word}
0x02ccd56b: jmp 0x02c8c930 ; {runtime_call}

Tuesday, September 6, 2011

JDK 7 Print JIT'ed code

>> jdk1.7.0/bin/java -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly t4 100000

Output:

Java HotSpot(TM) Client VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
32 1 java.lang.String::hashCode (67 bytes)
Loaded disassembler from hsdis-i386.dll

...
... String methods such as hashCode(), charAt() have been removed for clarity
...

Decoding compiled method 0x0290db08:
Code:
[Disassembling for mach='i386']
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} 'theSum' '(I)I' in 't4'
# parm0: ecx = int
# [sp+0x20] (sp of caller)
0x0290dc00: mov %eax,0xffffd000(%esp)
0x0290dc07: push %ebp
0x0290dc08: sub $0x18,%esp ;*bipush
; - t4::theSum@0 (line 15)
0x0290dc0b: mov $0x0,%eax
0x0290dc10: mov $0x0,%esi
0x0290dc15: jmp 0x0290dc29 ;*iload
; - t4::theSum@11 (line 18)
0x0290dc1a: xchg %ax,%ax
0x0290dc1c: add $0xbb,%esi
0x0290dc22: inc %eax ; OopMap{off=35}
;*goto
; - t4::theSum@26 (line 18)
0x0290dc23: test %eax,0x1d0100 ;*goto
; - t4::theSum@26 (line 18)
; {poll}
0x0290dc29: cmp %ecx,%eax
0x0290dc2b: jl 0x0290dc1c ;*if_icmpge
; - t4::theSum@14 (line 18)
0x0290dc2d: mov %esi,%eax
0x0290dc2f: add $0x18,%esp
0x0290dc32: pop %ebp
0x0290dc33: test %eax,0x1d0100 ; {poll_return}
0x0290dc39: ret
0x0290dc3a: nop
0x0290dc3b: nop
0x0290dc3c: mov %fs:0x0,%esi
0x0290dc44: mov 0xfffffff4(%esi),%esi
0x0290dc47: mov 0x184(%esi),%eax
0x0290dc4d: movl $0x0,0x184(%esi)
0x0290dc57: movl $0x0,0x188(%esi)
0x0290dc61: add $0x18,%esp
0x0290dc64: pop %ebp
0x0290dc65: jmp 0x028dba40 ; {runtime_call}
0x0290dc6a: hlt
0x0290dc6b: hlt
0x0290dc6c: hlt
0x0290dc6d: hlt
0x0290dc6e: hlt
0x0290dc6f: hlt
[Exception Handler]
[Stub Code]
0x0290dc70: call 0x0290bb80 ; {no_reloc}
0x0290dc75: push $0x5c3ccd40 ; {external_word}
0x0290dc7a: call 0x0290dc7f
0x0290dc7f: pusha
0x0290dc80: call 0x5c2bf5f0 ; {runtime_call}
0x0290dc85: hlt
[Deopt Handler Code]
0x0290dc86: push $0x290dc86 ; {section_word}
0x0290dc8b: jmp 0x028cc930 ; {runtime_call}
1377 2 % t4::main @ 9 (26 bytes)
Decoding compiled method 0x0290dd48:
Code:
[Disassembling for mach='i386']
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} 'main' '([Ljava/lang/String;)V' in 't4'
0x0290de50: mov %eax,0xffffd000(%esp)
0x0290de57: push %ebp
0x0290de58: sub $0x28,%esp ;*aload_0
; - t4::main@0 (line 5)
0x0290de5b: cmpl $0x0,0x8(%ecx) ; implicit exception: dispatches to 0x02
90dee9
0x0290de62: jbe 0x0290def3
0x0290de68: mov 0xc(%ecx),%ecx ;*aaload
; - t4::main@2 (line 5)
0x0290de6b: mov $0xa,%edx ;*invokestatic parseInt
; - java.lang.Integer::parseInt@3 (line
527)
; - t4::main@3 (line 5)
0x0290de70: nop
0x0290de71: nop
0x0290de72: nop
0x0290de73: call 0x028cd5c0 ; OopMap{off=40}
;*invokestatic parseInt
; - java.lang.Integer::parseInt@3 (line
527)
; - t4::main@3 (line 5)
; {static_call}
0x0290de78: mov $0x0,%esi
0x0290de7d: jmp 0x0290deac ;*iload_2
; - t4::main@9 (line 8)
0x0290de82: xchg %ax,%ax
0x0290de84: mov $0x0,%edi
0x0290de89: mov $0x0,%ebx
0x0290de8e: jmp 0x0290dea1 ;*iload
; - t4::theSum@11 (line 18)
; - t4::main@15 (line 9)
0x0290de93: nop
0x0290de94: add $0xbb,%ebx
0x0290de9a: inc %edi ; OopMap{off=75}
;*goto
; - t4::theSum@26 (line 18)
; - t4::main@15 (line 9)
0x0290de9b: test %eax,0x1d0100 ;*goto
; - t4::theSum@26 (line 18)
; - t4::main@15 (line 9)
; {poll}
0x0290dea1: cmp %eax,%edi
0x0290dea3: jl 0x0290de94 ;*if_icmpge
; - t4::theSum@14 (line 18)
; - t4::main@15 (line 9)
0x0290dea5: inc %esi ; OopMap{off=86}
;*goto
; - t4::main@22 (line 8)
0x0290dea6: test %eax,0x1d0100 ;*goto
; - t4::main@22 (line 8)
; {poll}
0x0290deac: cmp %eax,%esi
0x0290deae: jl 0x0290de84 ;*if_icmpge
; - t4::main@11 (line 8)
0x0290deb0: add $0x28,%esp
0x0290deb3: pop %ebp
0x0290deb4: test %eax,0x1d0100 ; {poll_return}
0x0290deba: ret ;*return
; - t4::main@25 (line 12)
0x0290debb: mov %eax,0xffffd000(%esp)
0x0290dec2: push %ebp
0x0290dec3: sub $0x28,%esp
0x0290dec6: mov 0x4(%ecx),%esi
0x0290dec9: mov (%ecx),%edi
0x0290decb: mov %ecx,(%esp)
0x0290dece: mov %esi,0x1c(%esp)
0x0290ded2: mov %edi,0x18(%esp)
0x0290ded6: call 0x5c19ad50 ; {runtime_call}
0x0290dedb: mov 0x18(%esp),%edi
0x0290dedf: mov %edi,%esi
0x0290dee1: mov 0x1c(%esp),%edi
0x0290dee5: mov %edi,%eax
0x0290dee7: jmp 0x0290deac
0x0290dee9: call 0x0290a850 ; OopMap{ecx=Oop off=158}
;*aaload
; - t4::main@2 (line 5)
; {runtime_call}
0x0290deee: call 0x0290a850 ; OopMap{ecx=Oop off=163}
;*aaload
; - t4::main@2 (line 5)
; {runtime_call}
0x0290def3: movl $0x0,(%esp)
0x0290defa: call 0x0290a550 ; OopMap{ecx=Oop off=175}
;*aaload
; - t4::main@2 (line 5)
; {runtime_call}
0x0290deff: nop
0x0290df00: nop
0x0290df01: mov %fs:0x0,%esi
0x0290df09: mov 0xfffffff4(%esi),%esi
0x0290df0c: mov 0x184(%esi),%eax
0x0290df12: movl $0x0,0x184(%esi)
0x0290df1c: movl $0x0,0x188(%esi)
0x0290df26: add $0x28,%esp
0x0290df29: pop %ebp
0x0290df2a: jmp 0x028dba40 ; {runtime_call}
0x0290df2f: hlt
[Stub Code]
0x0290df30: nop ; {no_reloc}
0x0290df31: nop
0x0290df32: mov $0x0,%ebx ; {static_stub}
0x0290df37: jmp 0x0290df37 ; {runtime_call}
[Exception Handler]
0x0290df3c: call 0x0290bb80 ; {runtime_call}
0x0290df41: push $0x5c3ccd40 ; {external_word}
0x0290df46: call 0x0290df4b
0x0290df4b: pusha
0x0290df4c: call 0x5c2bf5f0 ; {runtime_call}
0x0290df51: hlt
[Deopt Handler Code]
0x0290df52: push $0x290df52 ; {section_word}
0x0290df57: jmp 0x028cc930 ; {runtime_call}

t4.java

public class t4 {

public static void main(String[] args) {

int count = Integer.parseInt(args[0]);
for(int i=0; i theSum(count);
}
}

public static int theSum(int count) {
int A = 88;
int B = 99;
int sum = 0;
for (int i = 0; i < count; i++)
sum += A + B;

return sum;
}
}

Wednesday, July 20, 2011

Geoserver : Implementing a RESTful Service

I was following this tutorial
http://docs.geoserver.org/stable/en/developer/programming-guide/rest-ser...

to add a rest service endpoint to geoserver 2.1.1 and hit a few snags:
1. must modify restconfig applicationContext.xml
and
add the "hello" bean
and
routes mapping
(by "modify" i mean re-build the module, and the web/app module)

2. "txt" extension does not map to any MediaType, hence if we try
http://localhost:8080/geoserver/rest/hello.txt
we will get HTTP Error 500.

3. therefore we use hello.json, so we have to add
formats.add(new StringFormat( MediaType.APPLICATION_JSON ));
into HelloResource.java

4. we can go to
http://localhost:8080/geoserver/rest/hello.json
and now can successfully get the json file