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: jcmd {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.