Uncategorized

Load, Execute and Unload Application classes in JVM

Summary:

           We usually experience some kind of delay if we have to run a java program in any environment. It will take good amount of time to create a process to run the JVM and on top of that load the application classes and execute them. In some documents it is described as a cold start problem.

          What if we continuously run a  JVM process and dynamically load, execute and unload those classes from JVM. This doesn’t need to create a JVM process and we just need to load and fire those classes.

 How this can work?

Every time when we want to execute a piece of java code, load the compiled class files using a new instance of class loader in a JVM. Each class loader instance can act as a container for those loaded application classes. Each instance of the class loader will have its own set of classes and they are part of class loader which is loading them.

(Same class can be loaded multiple times if it loaded by multiple instances of class loaders i.e one for each class loader instance).

 Ideally URLClassLoader can be used to load classes from a jar file. And load and execute the required classes. We can unload those classes by simply garbage collecting the newly created classloader instance. This intern, make all those classes loaded by this class loader to be available for GC form metaspace. And metaspace can be cleaned by garbage collectors for loading new classes.

This is analogous to aws lambda’s, but we don’t need to create those JVM processes each time we want to run a piece of java code.

Code

Load the “fatjar” file into the running JVM

Path jarFilePath = FileUtil.saveFile(fileName, multipartFile);

Load the classes using a custom class loader

URL url = jarFilePath.toUri().toURL();

URLClassLoader child = new URLClassLoader(new URL[] { url });

Load the class definition and invoke using following code

Class classToLoad = Class.forName(fullClassName, true, child);

Method method = classToLoad.getDeclaredMethod(methodName);

Object instance = classToLoad.newInstance();

Object result = method.invoke(instance);

Prototype:

The application has been developed using spring boot which is locate at https://bitbucket.org/prabhukvn/tinlet/src/develop/

The above application can be tested with a sample application,

https://bitbucket.org/fastcartservices/tinlet-ts/src

How to test?

Run the tinlet application as a spring boot app and use the following command to test it

curl –location –request POST ‘localhost:8080/tinlet/run’ \
–form ‘file=@”/C:/prabhukvn/projects/tinlet-ts/target/tinlet-ts-0.0.1-SNAPSHOT-jar-with-dependencies.jar”‘ \
–form ‘fullClassName=”com.kvn.tinletts.TinletOne”‘ \
–form ‘methodName=”hello”‘

you can import this command into postman too.

Uncategorized

A Quick Reference To HTTP

HTTP 0.9 Protocol:

  • Defined in 1991
  • Latency is not at all a factor in HTTP 0.9
  • In order to perform an http request client has to open a new TCP connection which is closed by server after responding to it.
  • HTTP 0.9 User 3 way hand shake mechanism to establish a connection
  • Its s simple text based protocol
  • Only GET Method is allowed and Response Is HTML
  • No Headers and Status Codes
  • Invented by Tim Berners-lee at CERN
  • Need a TCP connection for each Request

TCP 3 way Handshake:

HTTP 0.9 using telnet

HTTP 1.0 Protocol:

  • Introduced in 1996
  • HEAD and POST Methods were added
  • Concept of header fields are introduced
  • User-Agent introduced in Request (for debugging purpose)
  • Content-Length introduced in Response (to identify the proper response)
  • Caching , Authorization etc
  • Still it Needs a TCP connection for each Request
  • Status Codes are introduced
  • Non-HTML can also be transmitted over this protocol

Telnet Using HTTP 1.0:

HTTP 1.1 Protocol:

  • Published om 1997
  • Persistent Connection Introduced
  • The same connection can be used for consecutive request for single embedded documents like images etc.
  • Chunked Responses were supported
  • HOST header has been introduced. This allowed hosting different domains from same IP address
  • Content Negotiation, encoding and type are introduced.
  • GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS

Telnet Using HTTP 1.1

Keep-alive Header:

 This header allowed the connection to be opened for some time

Keep-Alive: timeout=600,max100

Connection: Keep-Alive

 

Telnet Using Keep Alive HTTP 1.1

HTTP/2 protocol:

  • Started in 2015
  • Http2 is a binary, multiplexed, network protocol
  • Frames and streams are used to communicate using this protocol
  • Frames are exchanged over TCP connection instead of text based messages. The following frame types are available.
  • HEADERS, DATA,SETTINGS, or GOAWAY are different frame types.

There are two ways to use http2 protocol

  1. Using upgrade header
    1. Send an http connection with upgrade header

GET /index.html HTTP/1.1

Host: server.example.com

Connection: Upgrade, HTTP2-Settings

Upgrade: h2c

HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>

  1. Http 2 compatible server will accept the connection with switching protocols.

HTTP/1.1 101 Switching Protocols

Connection: Upgrade

Upgrade: h2c

[ HTTP/2 connection …

ALPN: Application level Protocol Negotiation:

ALPN allows a TLS connection to negotiate which application level will be running across it.

After establishing an HTTP/2 connection each endpoint has to send a connection preferences as a final confirmation and to establish the initial settings for http2 connection.

CURL Using HTTP 2.0

Here is the code rut a jetty server with http2 protocol

https://github.com/prabhukvn/springboot-jetty-http2

Uncategorized

How to check runtime log implementer in spring boot

Spring/ spring boot comes with default logger configuration for application logging. Spring uses logging fa├žade library called sl4j, hence we can easily change underlying logger implementation by simply adding the required jar files in the classpath. Spring/ spring boot by default picks logabck implementer for application logging. However this can be easily changed by adding other implementations like log4j and removing logback. But if you want to check the current runtime library which is getting used in spring application then simply add following controller and get the run time implenter.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/logger")
public class SimpleController {

	private static final Logger LOGGER = LoggerFactory.getLogger(SimpleController.class);
	

	
	@GetMapping("/test")
	public Class<? extends Logger> checkLoger() {
		
		return LOGGER.getClass();
		
	}
}

you can even log runtime class if you want to.