Friday, August 13, 2021

Generate Java thread dump

Often times we need to know what are the processes that are running in our Java app and one way to understand is to get the list of processes which usually called as thread dump.

The two steps to get the thread dump:

1. Get Java pid
    jcmd or jps can be used for retrieving the pid.






2. Generate thread dump

Command: jstack {pid}
















Note:
To help with understanding the thread dump better, we can redirect output the thread dump to a file and use the online thread dump analyzer, one of my favorite tool is fastThread.

Sunday, September 22, 2019

Loading external jar for SpringBoot

In case one builds one Springboot app which requires jar to be provided on runtime, here's the recipe:

  1. Change "Main-Class" attribute in jar manifest, here's one example of configuration in gradle:
    bootJar {
        manifest {
            attributes(
                "Main-Class": "org.springframework.boot.loader.PropertiesLauncher"
            }
        }
  2. To run the app, add loader.path parameter pointing to the folder location of the jar
    java -Dloader.path=lib/ -jar application.jar
Tips:
  1.  Default "Main-Class" in Springboot jar
    "Main-Class": "org.springframework.boot.loader.PropertiesLauncher
  2. "Start-Class" attribute in the manifest points to the main class, the class annotated with SpringBootApplication

Tuesday, March 12, 2019

Spring Boot Quartz - Custom Scheduler Factory using QuartzProperties

To have Quartz scheduler in a spring boot project we can follow the steps here.
The example on the link above requires separate properties file for quartz (or manually injecting the property values, see here).

To do it in a cleaner way, quartz configuration should be placed together in the application.yml file. Follow the steps below to adjust the configuration bean:
1. Inject QuartzProperties
@Autowired
QuartzProperties quartzProperties

2. Use the quartz properties on your schedulerFactory
schedulerFactory.setQuartzProperties(asProperties(quartzProperties.getProperties()))

private Properties asProperties(Map source) {
    Properties properties = new Properties();
    properties.putAll(source);
    return properties;
}

3. Done!

Sample quartz configuration in application.yml file:
quartz:
  job-store-type: jdbc
  jdbc:
    initialize-schema: embedded
  overwrite-existing-jobs: true
  scheduler-name: TheScheduler
  properties:
    org:
      quartz:
        scheduler:
          instanceName: TheScheduler
          instanceId: AUTO
        threadPool:
          class: org.quartz.simpl.SimpleThreadPool
          threadCount: 10
          threadPriority: 5
        jobStore:
          misfireThreshold: 60000
          class: org.quartz.impl.jdbcjobstore.JobStoreTX
          driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
          useProperties: false
          tablePrefix: QRTZ_
          isClustered: true
          clusterCheckinInterval: 20000


Reference:

  • https://www.baeldung.com/spring-quartz-schedule
  • https://dzone.com/articles/integrating-quartz-withspring


Wednesday, January 23, 2019

OpenVPN Server Setup

If you ever need to setup a vpn either for securing your communication (read: internet privacy) or providing remote access to your server, OpenVPN might be one good try.

Just finished working on OpenVPN setup on Ubuntu, here's the how-to link:
https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-16-04

Several notes (all the commands below are executed as root):

1. Configuration file

/etc/openvpn/server.conf

2. Some useful commands
Check status: systemctl status openvpn@server 
Start: systemctl start openvpn@server 
Stop: systemctl stop openvpn@server 
Starts automatically: systemctl enable openvpn@server 
Check OpenVPN tun0 interface up: ip addr show tun0

3. Allow client to client connection
- Edit server.conf enable client-to-client
# Uncomment this directive to allow different
# clients to be able to "see" each other.
# By default, clients will only see the server.
# To force clients to only see the server, you
# will also need to appropriately firewall the
# server's TUN/TAP interface.
client-to-client
- Restart openvpn service

4. Adding new client
cd ~/openvpn-ca
source vars
./build-key-pass client1
(change client1 to any client name)
Note:
the defaults should be populated, so you can just hit ENTER to continue. Leave the challenge password blank and make sure to enter y for the prompts that ask whether to sign and commit the certificate.
5. Generate client config
cd ~/client-configs
./make_config.sh client1
(client1 should be replace with the client name used to generate the key)
File will be generated in ~/client-configs/files/client1.ovpn
Transfer the ovpn file to client
6. Client Setup
For Mac, tunnelblick works for me (https://tunnelblick.net/).
For Windows, OpenVPN provides one (https://openvpn.net/community-downloads/)

Monday, October 08, 2018

Enable gc log

When your Java app is running very slow there's a chance that it is caused by some pauses in your app which in turn caused by the diligent garbage collector who loves to take its time cleaning up the memory for you way too often and too long :)

These two steps you might want to do to make sure that it was GC doing its job:
1. Extract the GC log from your app
2. Analyze the log

Extracting GC Log

For extracting the gc log, here's my preferred settings:

-XX:+PrintGCDetails
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintGCDateStamps
-Xloggc:gc.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=2000k


Add those parameters above on your java runtime parameters, for tomcat you could edit catalina.sh (or catalina.bat), find JAVA_OPTS and add them there.

Restart your Java app or app server and find gc.log on the current directory where you run your java app.

Analyzing GC Log

Refer to the reference 1 below on how to learn to interpret the gc log.
For the tools, choices are you do it using offline tool or online tool.
1. Offline
I'm using GC Viewer (see reference 3 below), simple and easy tool

2. Online
Try gceasy.io, it analyzes your gc log quite awesome :)


Reference:

1. https://dzone.com/articles/enabling-and-analysing-the-garbage-collection-log
2. http://gceasy.io
3. https://github.com/chewiebug/GCViewer

Thursday, October 04, 2018

Updating /etc/hosts in Android emulator

Why? think of it like when all you want is to redirect the target server to another server and you cannot or should not update the dns server and all you need is just one or two lines on the right place ;)

Isn't it as simple as going in and change one or two things? Yes, if it's allowed :)
Anyway here's how we can do it in five simple steps:

1. Assuming emulator is already set up, open the shell and go to the emulator directory under the sdk directory. Start the emulator with this command:

emulator -writable-system -netdelay none -netspeed full -avd {emulator_name}
e.g.
emulator -writable-system -netdelay none -netspeed full -avd Nexus_5X_API_25

2. Go to root mode
Open the shell and run the command:
adb root
3. Remount system partition
adb remount
4. Pull hosts file, edit it as needed
adb pull /etc/hosts hosts
5. Push it back
adb push hosts /etc/hosts

And... we're done, enjoy!

Friday, August 10, 2018

Certificate check and installation (Java)

Been dealing with self signed certificate quite sometimes and found myself always googled around for the how-tos, guess it's time to write it down here (for checking back later on which I guess I will... ;)

And here's the famous security exception:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Goal is to install a self signed certificate in Java keystore so that Java app can open https connection to the server without raising any security error or trying to skip the security checking at all.


How to:

Step 1. Extracting the certificate
Using openssl:
1. Grab the target certificate from the server
openssl s_client -showcerts -verify 5 -connect {HOST:PORT} | tee thecert.txt
Type QUIT and press enter/return, certificate will be captured in thecert.txt
 2. Generate cert file
openssl x509 -inform PEM -in thecert.txt -out thecert.crt
3. Verify cert
openssl x509 -in thecert.crt -text -noout

In case you are dealing with a development environment, you might want to install the root and intermediate cert in your keystore so that you don't have to import each and every certificate that belongs to another system integrated. See below on how to extract the root and intermediate cert.

Step 2. Installing the certificate
Next is to install the extracted certificate in the keystore, one way is to install it right on the jre's keystore and the more secure way is to setup a local truststore and pass it as JVM parameter (e.g. -Djavax.net.ssl.trustStore=./LocalTrustStore)
1. Import the certificate
     keytool -import -alias {THE_ALIAS} -keystore {PATH_TO_KEYSTORE} -file {CERTIFICATE FILE}
    Default jre keystore can be found under jre/lib/security directory.
2. Verify it
   keytool -list -keystore {PATH_TO_KEYSTORE} -alias {THE_ALIAS}

Step 3. Testing using SSLPoke
Get SSLPoke here, it's one nice utility to check whether you have successfully import the certificate or not.
java SSLPoke {URL} {PORT}
e.g. java SSLPoke myserver 1234



Reference:

1. https://operational.io/openssl-commonly-used-commands/
2. https://gist.github.com/4ndrej/4547029
2. Extract root and intermediate
  1. openssl x509 -in cert.x509 -text Find the URL of the signing certificate.
  2. curl (url) >signer.der Download the signing certificate to a file (DER format in my case).
  3. openssl x509 -inform der -in signer.der -out signer.pem Convert signing certificate to PEM (X.509) format.
  4. openssl x509 -in signer.pem -text Confirm your results. Repeat procedure as necessary all the way up the certificate chain.

Tuesday, April 24, 2018

Nginx Reverse Proxy Formulae

It should be simple but it's just not that simple, that's the reason I'm writing down some example for the proxy pass configuration here.

The reference link can be found here.

Theory:

The keyword is "If the URI is specified along with the address, it replaces the part of the request URI that matches the location parameter.....  If the address is specified without a URI, or it is not possible to determine the part of URI to be replaced, the full request URI is passed (possibly, modified)."

Note:
1.If you specify any URI along with the server address it will replace the request URI part on the location
2. If you don't specify any URI, the full request URI on the location is appended to the target URL


Without further ado, here's some examples:
Assume nginx is setup on localhost and will redirect to www.example.com.

Configuration #1
location /some/path {
      proxy_pass http://www.example.com/link;
}
URL: http://localhost/some/path
Passed to: http://www.example.com/link
URL: http://localhost/some/path/hello
Passed to: http://www.example.com/link/hello
URL: http://localhost/some/path/
Passed to: http://www.example.com/link/


Configuration #2
location /some/path {
      proxy_pass http://www.example.com/;
}
URL: http://localhost/some/path
Passed to: http://www.example.com/
URL: http://localhost/some/path/hello
Passed to: http://www.example.com/hello
URL: http://localhost/some/path/
Passed to: http://www.example.com/


Configuration #3
location /some/path {
      proxy_pass http://www.example.com;
}
URL: http://localhost/some/path
Passed to: http://www.example.com/some/path
URL: http://localhost/some/path/hello
Passed to: http://www.example.com/some/path/hello
URL: http://localhost/some/path/
Passed to: http://www.example.com/some/path/


Configuration #4
location /some {
      proxy_pass http://www.example.com/;
}
URL: http://localhost/some
Passed to: http://www.example.com/
URL: http://localhost/some/path/hello
Passed to: http://www.example.com/path/hello
URL: http://localhost/some/
Passed to: http://www.example.com/
URL: http://localhost/some/hello?name=me
Passed to: http://www.example.com/hello?name=me

Thursday, September 03, 2015

Estimate database usage - Oracle

One question always haunts me a bit, "Could you provide the database machine requirement?".
Here's one method I often use to estimate the size for Oracle database:
1.  SELECT SUM(BYTES) FROM (
select SEGMENT_NAME, SUM(BYTES)/(1024*1024) BYTES from user_extents
where segment_type = 'TABLE'
and segment_name like 'ACT_%'
GROUP BY SEGMENT_NAME);

select SEGMENT_NAME, SUM(BYTES)/(1024*1024) BYTES from user_extents
where segment_type = 'TABLE'
and segment_name like 'ACT_%'
GROUP BY SEGMENT_NAME;

Tomcat JMX Monitoring

Monitoring Tomcat's resources could be done using the JConsole app which already included in the JDK. In order to monitor Tomcat, we also need to prepare the Tomcat first.



To configure Tomcat in *nix environment, you need to add the parameter below when starting tomcat:
-Dcom.sun.management.jmxremote
  -Dcom.sun.management.jmxremote.port=%my.jmx.port%
  -Dcom.sun.management.jmxremote.ssl=false
  -Dcom.sun.management.jmxremote.authenticate=false

To add the configuration above, one of the way is as below:
1. Open your catalina.sh
2. Add below line (example port is 12300)


3. Restart your tomcat
4. If you need to access it from other computers, make sure the firewall configuration  allows the configured port to be accessed from outside
5. In case the remote connection is not working, try to add below line in the configuration
    -Dcom.sun.management.jmxremote.host=localhost


Reference:
- https://tomcat.apache.org/tomcat-7.0-doc/monitoring.html
- http://docs.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html

Tuesday, August 11, 2015

Resize LVM Partition in Virtual Box


Here's a note on how to resize LVM partition in VirtualBox
1. VBoxManage modifyhd vdi_path --resize new_size_in_mb
2. Resize the disk.
    a. Run the VM
    b. Open terminal/console and execute command below
        + df
           Write down the logical mapping, in my case it is /dev/mapper/vg_iplus-lv_root
     
     
        + fdisk -l
           Write down the Device name, in my case /dev/sda2
     
 + fdisk /dev/sda
     The next steps will delete the partition to resize, recreate the partition and make it primary. Then resize the partition to the new size and write the changes.
 + Still in fdisk, delete the partition
     input: d
 + Still in fdisk, select the device to partition number. In my case it is 2 (/dev/sda2)
     input: 2
   

  + Still in fdisk, create new partition and select the same partition as in previous steps (e.g. 2)
     Input: n
     Input: 2


  + Set the size for the new partition, set it to occupy all available space (or as preferred)
      Input: enter (twice to set default size)


  + Commit the changes
     Input: w

   + Reboot server
      Command: reboot

   + Resize the physical volume
      Command: pvresize /dev/sda2
     /dev/sda2 refers to the partition changed previously

   + Verify the new size, make sure the new size is applied
       Command: pvscan

   + Extend the logical volume to take all free space
      Command: lvextend -l +100%FREE /dev/mapper/fedora-root

   + Resize the file system
      Command: resize2fs /dev/mapper/vg_iplus-lv_root

   + Verify the new changes
      Command: df

And we're done! :)


Reference:
https://blog.jyore.com/2013/06/virtualbox-increase-size-of-rhelfedoracentosscientificos-guest-file-system/

Sunday, June 21, 2015

Find blocking query - Oracle

If you have a query that stops and it seems that it will never end, you might have another query blocking it. Here's one help to find out which query blocking it.

SELECT s1.username || '@' || s1.machine
    || ' ( SID=' || s1.sid || ' )  is blocking '
    || s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ) ' AS blocking_status
    FROM v$lock l1, v$session s1, v$lock l2, v$session s2
    WHERE s1.sid=l1.sid AND s2.sid=l2.sid
    AND l1.BLOCK=1 AND l2.request > 0
    AND l1.id1 = l2.id1
    AND l1.id2 = l2.id2;


References:
http://www.oraclerecipes.com/monitoring/find-blocking-sessions/

Saturday, August 23, 2014

SQLServer tips

This page would be a growing list for things related to SQLServer. Mostly kept for the rainy season :)

1. How to find most expensive queries (for cache query plans only) 
(ref: http://blog.sqlauthority.com/2010/05/14/sql-server-find-most-expensive-queries-using-dmv/)

SELECT TOP 10 SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.TEXT)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads,
qs.total_logical_writes, qs.last_logical_writes,
qs.total_worker_time,
qs.last_worker_time,
qs.total_elapsed_time/1000000 total_elapsed_time_in_S,
qs.last_elapsed_time/1000000 last_elapsed_time_in_S,
qs.last_execution_time,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY qs.total_logical_reads DESC -- logical reads
-- ORDER BY qs.total_logical_writes DESC -- logical writes
-- ORDER BY qs.total_worker_time DESC -- CPU time

2. Queries taking longest elapsed time
SELECT TOP 10
qs.total_elapsed_time / qs.execution_count / 1000000.0 AS average_seconds,
qs.total_elapsed_time / 1000000.0 AS total_seconds,
qs.execution_count,
SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) AS individual_query,
o.name AS object_name,
DB_NAME(qt.dbid) AS database_name
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
where qt.dbid = DB_ID()
ORDER BY average_seconds DESC;

3. Queries doing most I/O

SELECT TOP 10
(total_logical_reads + total_logical_writes) / qs.execution_count AS average_IO,
(total_logical_reads + total_logical_writes) AS total_IO,
qs.execution_count AS execution_count,
SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END – qs.statement_start_offset)/2) AS individual_query,
o.name AS object_name,
DB_NAME(qt.dbid) AS database_name
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
where qt.dbid = DB_ID()
ORDER BY average_IO DESC;


4. Find blocking and blocked queries (sessions)
Use sp_who2

Friday, August 15, 2014

Create swap file for your VPS

Just got a VPS for your own use? RAM only 512MB? or maybe you are accustomed to out of memory error and need a way to increase your memory.
Then you got to have a swap file for your VPS, the size of which will depend on your usage.

One thing to remember, swap file is created on your storage. So don't expect it to be as fast as your RAM.

Here are the steps you can follow (works on Ubuntu 12.04):
1. Check for existing swap file, if you already have one then all are good.
    swapon -s

2. Create your file for the swap file
sudo dd if=/dev/zero of=/swapfile bs=1024 count=256k

3. Set it as swap file
sudo mkswap /swapfile

4. Register the swap file
sudo swapon /swapfile

5. Make it permanent on the system
sudo nano /etc/fstab

And add the following line at the end:
/swapfile       none    swap    sw      0       0 

6. Set the swappiness
echo 10 | sudo tee /proc/sys/vm/swappiness
echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf

7. Protect the file
sudo chown root:root /swapfile 

sudo chmod 0600 /swapfile


That's all, enjoy your VPS.

Reference:
https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-12-04

Monday, July 07, 2014

Configure reverse ssh tunneling

When you have a need to access your local PC from the internet, you might be interested in this blog.

Requirement:
1. Root access to a public server (or any kind of access as long as you can do things below :).
2. SSH client


Now, let's begin with the server:
1. Edit sshd_config located in /etc/ssh/ and add the line below
GatewayPorts clientspecified

2. Restart sshd
sudo service ssh restart

That's all for the server.


To the local PC we go:
1. Create reverse ssh tunneling using ssh client.
Open a terminal/console to run the ssh client. In windows you might use Putty.
ssh user@server -R server:serverport:localdestination:localport

2. Test the connection by using telnet
telnet server serverport
Expect no connection refused :)


The steps above is very simple but requires some configuration changes in the public server.
There's a more secure way but requires more effort on the client side which means only geek will be able to access it :) I'll discuss it later on a separate blog.

Setting up vnc for ubuntu desktop

If your installation is ubuntu desktop and you need to remote it using vnc, the steps below might help you to do it:
1. Update your package list
sudo apt-get update

2. Install Gnome desktop environment essential component and Gnome session manager
sudo apt-get install gnome-core gnome-session-fallback

3. Install vnc server
sudo apt-get install vnc4server

4. Start the vnc server
vncserver 
Note: find out the console port being assigned to you. There is a way to start up the connection with a pre defined port number (e.g. vncserver :1)

Example: the assigned port is 1 (5901)
New 'server:1 (server)' desktop is server:1

Starting applications specified in /home/user/.vnc/xstartup

Log file is /home/user/.vnc/user:1.log

5. Edit the xstartup file located /home/user/.vnc/ as below.
At first, when you open the vnc connection there will be only a terminal. You will need to start the gnome-session for the vnc connection.
#!/bin/sh

# Uncomment the following two lines for normal desktop:
 unset SESSION_MANAGER
#exec /etc/X11/xinit/xinitrc

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &

gnome-session --session=gnome-classic &

6. Restart the vncserver by killing it first then starting it up again
vncserver -kill :1


To access vnc from the client, you need to install vnc viewer app. 
The sample url for vnc: server_url:5901
the port number is assigned when you start the vnc connection.


Up to now, for ubuntu server I use Xfce desktop environment instead of gnome. It is lightweight and somehow I still can't setup the gnome env under vnc :)


Reference link:
http://coddswallop.wordpress.com/2012/05/09/ubuntu-12-04-precise-pangolin-complete-vnc-server-setup/

Friday, January 31, 2014

Configuring php for handling large file upload

Cut it short, what I need is to configure my nginx-php to be able to handle around 200M file upload.
So here are the configuration changes I need to make:
1. nginx.conf
    usually the file is placed in /etc/nginx/nginx.conf.
    The parameters to add inside http are:
    - client_max_body_size: specifies the maximum accepted body size of a client request
    - client_body_timeout: sets the read timeout for the request body from client
    http {

        ##
        # Basic Settings
        ##

        client_max_body_size 200m;
        client_body_timeout 600s;

       
        ....
   }

2. php.ini
    Since I use php5-fpm, this file is placed in /etc/php5/fpm/php.ini
    The parameters to change is:
    - post_max_size: Sets max size of post data allowed
    - upload_max_filesize: The maximum size of an uploaded file
    - max_execution_time:This sets the maximum time in seconds a script is allowed to run before it is terminated by the parser.
    - max_input_time:  This sets the maximum time in seconds a script is allowed to parse input data, like POST and GET.


After changing those variables, restart both nginx and php5-fpm and you're done!

Reference links:
http://wiki.processmaker.com/index.php/Nginx_and_PHP-FPM_Installation
https://rtcamp.com/tutorials/php/increase-file-upload-size-limit/
http://www.radinks.com/upload/config.php
http://wiki.nginx.org/HttpCoreModule#client_body_timeout

Tuesday, August 14, 2012

Struts2 in Websphere 6.1

Just when someone asked you if Java really delivers what it promises, especially about compile once run anywhere. I just deployed a webapp developed using Struts 2, Spring, Hibernate in Websphere 6.1. And as expected, the deployment failed. After a few googling around and friend's advice, it turns out that I have to configure some properties for the server.

Here are the properties:


















The new properties added are the last two, and here is a bit explanation on the property:
- com.ibm.ws.webcontainer.invokefilterscompatibility = true
 Quoted from ibm docs (see here)
With this custom property, the Web container calls custom servlet filters before looking for welcome files. Also, if the Web container cannot find a resource, it calls the custom servlet filters before creating a FileNotFoundException exception. This change enables the Web container to verify whether the custom servlet filters modify the path to a resource. 
In short, this property enables custom servlet filter to process http request and Struts 2 utilizes Servlet Filter.

- com.ibm.ws.webcontainer.assumefiltersuccessonsecurityerror = true
Quoted from ibm docs (see here)
When a request is received for a static file which does not exist, the web container calls defined servlet filters. If the filters do no successfully complete, a 404 error code is set. In a situation where application security is enabled, a security check is performed as part of filter invocation. Typically if the security check fails the web container considers the filters to have failed and still sets a 404 error code instead of the 401 error code that indicates the failure of a security check. The 404 error code enables the requester to access the static file without logging on.
 In short, just to be more secure this property is set to true. Anyway, this property doesn't have any thing to do with Struts 2.


To make sure everything works, don't forget to restart the server.



Friday, April 27, 2012

VirtualBox misc

A note for myself on my dealings with VirtualBox, refer to this link for complete command:
  • Changing the virtual harddisk UUID (.vdi)
    VBoxManage internalcommands sethduuid /VirtualMachine/virtualmachine.vdi
  • Resizing the virtual harddisk
    VBoxManage modifyhd virtualmachine.vdi --resize SIZE_MB
  • Disable time synchronization
    VBoxManage setextradata LHBU "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled" "1"   
          You need to restart your vbox instance if it is running when you execute the command.
          Unrecommended workaround is:
          Guest Windows: go to Services, find VirtualBox Guest Additions service and stop it. You will find that time synch is no longer working, but I'm not sure whether other functionalities regarding virtual box - host integration are affected or no.
          Guest Linux:  /etc/init.d/vboxadd-timesync stop
          Disclaimer! Never tried the linux version, found it during googling.

Wednesday, September 07, 2011

Tracking Hibernate SQL query and parameters

Every developer using Hibernate might need to know the SQL it generates and the parameters being sent. Normally to have the sql printed out to console, one only have to configure hibernate property show_sql to true. However the parameters are not printed out.

Luckily for me, I found this post on configuring the necessary log level to be able to print out the sql and parameters. Here are the configuration that I used:

org.hibernate.SQL=DEBUG
org.hibernate.type=TRACE