Java Error and exception

In Java, there are two main types of problems that can occur during the execution of a program: Errors and Exceptions.

1. Errors

Errors are serious issues that occur beyond the control of the application. These are typically problems related to the Java Virtual Machine (JVM) itself, such as:

  • StackOverflowError
  • OutOfMemoryError
  • VirtualMachineError

These errors are often unrecoverable and should not be handled in the code. When an error occurs, it’s best to let the system crash or shut down gracefully, as the environment may no longer be stable.

2. Exceptions

Exceptions are issues that arise during the normal operation of a program and can usually be anticipated and handled. For example:

  • Trying to read a file that doesn’t exist.
  • Invalid user input.
  • Attempting to divide by zero.

Java provides a robust mechanism to handle exceptions using try-catch-finally blocks. Exceptions are further categorized into two types:

a. Checked Exceptions

These are exceptions that are checked at compile time. The compiler requires the developer to handle these exceptions explicitly, either by using a try-catch block or by declaring them in the method signature using the throws keyword.

Examples:

  • IOException
  • SQLException

b. Unchecked Exceptions

These are exceptions that are not checked at compile time. They usually indicate programming bugs, such as logic errors or improper use of an API. These exceptions inherit from RuntimeException.

Examples:

  • NullPointerException
  • ArrayIndexOutOfBoundsException
  • IllegalArgumentException

Summary

Type Checked at Compile Time Typically Caused By Should Be Handled?
Error No JVM/Internal system issues No
Checked Exception Yes External issues (I/O, DB) Yes
Unchecked Exception No Programming bugs Yes (when possible)

Understanding the difference between errors and exceptions—and between checked and unchecked exceptions—helps in writing more robust and fault-tolerant Java applications.


Let me know if you’d like a more casual tone or if you want to turn this into a tutorial-style post!

Session and Token

Introduction

I am working with a login api, and therefore I have some notes about Session and Token (JWT - Json web token).

Session

The general practice of a login system should be to verify that the customer’s login information is correct. Then add a logged in attribute to the client’s session if it is correct. There are usually some tools that help us doing that. Generally the default name of the session(cookie) is “JSESSIONID”; Stored in the client’s cookie, so we don’t have to write any more complicated operations in the program.

Each time the Client Side send a request, we bring the session id along with it. Server side will take the session ID and find out the specific session from the many sessions stored in Server.
There it is, if there are 10000 user online, server need to store 10000 different session in the database. Which is a very high IO, also, there is also the problem of how to share sessions between multiple hosts.

To solve this problem, we normally use Redis.

JWT token

It is very popular to use JWT as a Token instead of session. jwt is a string encrypted by the server and issued to the client.
After receiving the token, the client sends a request with the token in case of need, so that the Server can decrypt and verify the identity.
Because the token itself stores the authentication information of the client. In general, the Server will no longer store the token after it is issued.
Note that, the token can actually be stored in a cookie.

JWT implementation

There are three part of a JWT, header, payload, signature

The whole thing will use base64 encode

  • alg: Cryptographic algorithms used
  • typ: JWT

Payload

  • iss: Issuer
  • sub: subject, can be the key value such as account no.
  • exp: expiration time

Signature

sign(hash(header+payload))

The signature also certifies that only the party holding the private key is the one that signed it.

Generating JWT

1
2
3
4
5
6
7
8
9
// JWT code here
Date expireDate = new Date(System.currentTimeMillis()+30*60*1000);

String jwtToken = Jwts.builder().setSubject(email)
.setExpiration(expireDate)
.signWith(SignatureAlgorithm.HS512, "secret")
.compact();

return jwtToken;

Check the token

  • notes 1 : Whenever the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema. The content of the header should look like the following: Authorization: Bearer <token>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class AuthorizationCheckFilter extends OncePerRequestFilter{

@Override
`protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException {
if(!req.getServletPath().equals("/api/v1/user/login")){


String authorHeader = req.getHeader(AUTHORIZATION);
String bearer ="Bearer "; // notes 1

if(authorHeader!= null && authorHeader.startsWith(bearer)){
try{
String token = authorHeader.substring(bearer.length());
Claims claims = Jwts.parser().setSigningKey("MySecret")
.parseClaimsJws(token).getBody();

System.out.println("JWT payload:"+claims.toString());

chain.doFilter(req, res);

}catch(Exception e){
System.err.println("Error : "+e);
res.setStatus(FORBIDDEN.value());

Map<String, String> err = new HashMap<>();
err.put("jwt_err", e.getMessage());
res.setContentType(APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(res.getOutputStream(), err);
}
}else{
res.setStatus(UNAUTHORIZED.value());
}
}else{
chain.doFilter(req, res);
}

}

}

The jwt implementation of nestjs
https://github.com/etklam/nestjs-jwt-implementation