Showing posts with label error. Show all posts
Showing posts with label error. Show all posts

Tuesday, 1 November 2022

Design error message for HTTP APIs using RFC 7807

 

In this post, I am going to talk about the RFC 7807, which documents the standard http error message structure.

 

If you are working with webservices, then you might have seen http error codes like below.

a.   400 (Bad Request)

b.   401 (Unauthorized)

c.    403 (Forbidden)

d.   404 (Not found)

e.   500 (Internal Server error)

f.     503 (Service unavailable)

g.   504 (Gateway timeout) etc.,

 

But sometimes, these http status codes alone not sufficient to convey the details about the error. To address this problem, we need a standardized error structure, that can be uniformly accepted by the applications and provide meaningful insights about the error. Here RFC 7807 comes into picture.

 

As per RFC 7807, error or problem details object has the following members.

 

Member

Data type

description

type

String

URI references that identifies the problem type.

title

String

A short, human-readable summary of the problem type. ‘title’ help the users who are not aware of semantics of URI and do not have the ability to discover them

status

number

Http Status code

detail

String

A human-readable explanation specific to this occurrence of the problem.

instance

String

A URI reference that identifies the specific occurrence of the problem.  It may or may not yield further information if dereferenced.

 

Example 


{
  "type": "https://demo.com/probs/insuffecient-funds",
  "title": "You do not have enough funds in the linked accounts.",
  "detail": "Your current balance is 2500, but that costs 7500.",
  "instance": "https://demo.net/account/12345/msgs/abc",
  "status" : 403
}

 

Apart from the standard members, you can add additional members to the error object to convey more details.

{
  "type": "https://demo.com/probs/insuffecient-funds",
  "title": "You do not have enough funds in the linked accounts.",
  "detail": "Your current balance is 2500, but that costs 7500.",
  "instance": "https://demo.net/account/12345/msgs/abc",
  "status" : 403
  "balance": 7500,
  "linked_accounts": [
    "https://example.net/account/12345",
    "https://example.net/account/67890"
  ]
}

 

Note

a.   Both "type" and "instance" accept relative URIs; this means that they must be resolved relative to the document's base URI

 

References

https://www.rfc-editor.org/rfc/rfc7807

 

 

Previous                                                 Next                                                 Home

Wednesday, 18 May 2022

How to solve the Error: Could not find or load main?

'Error: Could not find or load main class HelloWorld' error occur when you try to run the main class HelloWorld, but Java runtime unable to find it.

 

Let’s try to produce the error and see the possible options to resolve it.

 

Step 1: Create a folder hierarchy com/sample/app and define HelloWorld.java file in it.

 

HelloWorld.java

package com.sample.app;

public class HelloWorld {
	
	public static void main(String[] args) {
		System.out.println("Hello World");
	}

}

Folder hierarchy looks like below.


 

$tree
.
|____com
| |____sample
| | |____app
| | | |____HelloWorld.java

Step 2: Navigate to the folder, where package com is create and compile HelloWorld.java file by executing below command.

javac com/sample/app/HelloWorld.java


bash-3.2$ tree
.
|____com
| |____sample
| | |____app
| | | |____HelloWorld.java
bash-3.2$ 
bash-3.2$ javac com/sample/app/HelloWorld.java 
bash-3.2$ 
bash-3.2$ tree
.
|____com
| |____sample
| | |____app
| | | |____HelloWorld.class
| | | |____HelloWorld.java


Step 3: Run HelloWorld class file, by executing the command 'java com/sample/app/HelloWorld'.

 

bash-3.2$ java com/sample/app/HelloWorld
Hello World

Since, Java look into the current directory for the main class, program ran successfully. 

 How about running HelloWorld class from different directory?

Let's navigate to the root folder and try to run HelloWorld class.


bash-3.2$ cd /
bash-3.2$ 
bash-3.2$ java com/sample/app/HelloWorld
Error: Could not find or load main class com.sample.app.HelloWorld

We got this error, since Java class loader unable to find the main class HelloWorld in the current directory.

 

How to resolve this error?

Approach 1: Set the classpath using CLASSPATH variable. You can read this post for more details.

export CLASSPATH={path_to_the_parent_of_package_folder}

 

If you are using Windows system, use below statement

 

SET CLASSPATH={path_to_the_parent_of_package_folder}


In my case, I defined com/sample/app package hierarchy in /Users/krishna/Documents/technical-documents/examples folder.


export CLASSPATH=/Users/krishna/Documents/technical-documents/examples


Once you set the classpath, you can run the HelloWorld class from anywhere.


$export CLASSPATH=/Users/krishna/Documents/technical-documents/examples
$
$cd /
$
$java com/sample/app/HelloWorld
Hello World

You can even run using . syntax.

$java com.sample.app.HelloWorld
Hello World

Approach 2: Set the class path using -cp or -classpath option.

$java -cp /Users/krishna/Documents/technical-documents/examples com.sample.app.HelloWorld
Hello World
$
$java -classpath /Users/krishna/Documents/technical-documents/examples com.sample.app.HelloWorld
Hello World

Note

In case if you are using maven as a build tool for your project, it generate the class files under project_directory\target\classes folder.

 

 

 You may like

Interview Questions

Different ways to iterate over a map using for-each loop

How for-each or enhanced for loop works in Java?

How to solve UnsupportedClassVersionError in Java?

How to find the Java major and minor versions from a .class file

Can I run a class file that is compiled in lower environment?

How to solve UnsupportedClassVersionError in Java?

UnsupportedClassVersionError is thrown when the Java Virtual Machine attempts to read a class file and determines that the major and minor version numbers in the file are not supported.

 


This error occur, when you compile the Java class file in higher version (For Ex: java1.8) and try to run on lower version (Ex: Java 1.7)

 

Let’s experiment the same.

 

HelloWorld.java

public class HelloWorld {
	
	public static void main(String[] args) {
		System.out.println("Hello World");
	}

}

 

Let’s compile HelloWorld.java class using Jdk1.8.

$/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home/bin/javac -version
javac 1.8.0_311
$
$/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home/bin/javac HelloWorld.java 

 

Let’s run HelloWorld.class file using Jdk1.7.

$/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/bin/java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
$
$
$/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/bin/java HelloWorld
Exception in thread "main" java.lang.UnsupportedClassVersionError: HelloWorld : Unsupported major.minor version 52.0
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)

 

Oops, I got the error ‘java.lang.UnsupportedClassVersionError: HelloWorld : Unsupported major.minor version 52.0’.

 

Below table summarizes different major.minor versions of Jdk.

 

JDK version

Major version number

JDK 1.1

45

JDK 1.2

46

JDK 1.3

47

JDK 1.4

48

Java SE 5.0

49

Java SE 6.0

50

Java SE 7

51

Java SE 8

52

Java SE 9

53

Java SE 10

54

Java SE 11

55

Java SE 12

56

Java SE 13

57

Java SE 14

58

Java SE 15

59

Java SE 16

60

Java SE 17

61

 

From the error message, you can see the number 52, that means this class is compiled with Java SE 8 and not compatible with the current running environment.

 

How to resolve this error?

Solution 1: Upgrade Java runtime environment to the compiled version. In our example, we need to upgrade Java run time environment to 1.8.

 

Solution 2: Specify the target and source versions while compiling the class file.

Ex

javac -target 1.7 -source 1.7 HelloWorld.java

$/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home/bin/javac -target 1.7 -source 1.7 HelloWorld.java 
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning
$
$
$/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/bin/java HelloWorld
Hello World

 

References

https://en.wikipedia.org/wiki/Java_class_file

 


You may like

Interview Questions

Get the length of longest row in a two dimensional jagged array in Java

Quick guide to OutOfMemoryError in Java

StackOverFlowError vs OutOfMemoryError in Java

Different ways to iterate over a map using for-each loop

How for-each or enhanced for loop works in Java?

Monday, 16 May 2022

StackOverFlowError vs OutOfMemoryError in Java

In this post, I am going to explain the difference between StackOverFlowError and OutOfMemoryError. Let’s try to understand what is stack and Heap before dig further.

 

Stack and Heap memory

Stack is a special region in computer memory, that stores temporary variables like local variables, parameters, function calls etc., Stack works in last in first out (LIFO) order. Whenever a new local variable initialized inside a function, it is pushed onto the stack, when the function finished execution, all the local variables pushed by that function onto the stack are removed from the stack. Read this post  for more details.

 

Heap is a portion of memory where dynamic allocation and de allocations happen. When the application request for a new object, JVM allocates the memory in Heap. Heap memory is slightly slower to read from and written to, because pointer access is needed to access heap memory. The JVM allocates Java heap memory from the OS and then manages the heap for the Java application. Refer this post for more details.

 

StackOverflowError

StackOverflowError is related to stack memory area and it is thrown when a stack overflow occurs because an application recurses too deeply.

 


 

Let’s try to produce StackOverflowError.

 

StackOverflowErrorDemo.java

public class StackOverflowErrorDemo {

	static void fun() {
		fun();
	}

	public static void main(String args[]) {
		fun();
	}
}

 

Compile and run above application.

$javac StackOverflowErrorDemo.java 
$
$java StackOverflowErrorDemo
Exception in thread "main" java.lang.StackOverflowError
	at StackOverflowErrorDemo.fun(StackOverflowErrorDemo.java:4)
	at StackOverflowErrorDemo.fun(StackOverflowErrorDemo.java:4)
	at StackOverflowErrorDemo.fun(StackOverflowErrorDemo.java:4)
	at StackOverflowErrorDemo.fun(StackOverflowErrorDemo.java:4)
	at StackOverflowErrorDemo.fun(StackOverflowErrorDemo.java:4)
	at StackOverflowErrorDemo.fun(StackOverflowErrorDemo.java:4)
	at StackOverflowErrorDemo.fun(StackOverflowErrorDemo.java:4)

 

As you see the class ‘StackOverflowErrorDemo’, ‘fun()’ method calls itself recursively infinite times, which leads to the stack gets exhausted and endup in StackOverflowError.

 

How to resolve StackOverflowError?

a. Check your application code for infinite recursions and resolve them.

 

b. If there is no infinite recursion, try increasing the stack size. Refer this post to increase the stack size.

 

OutOfMemoryError

OutOfMemoryError Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.



OutOfMemoryError is related to Java Heapmemory. It typically occur, when the application request memory for a new object, but the heap is already full.

 

Let’s write a simple program to produce OutOfMemoryError.

 

OutOfMemoryErrorDemo.java

public class OutOfMemoryErrorDemo {

	public static void main(String[] args) {
		Integer obj[] = new Integer[Integer.MAX_VALUE];

		for (int i = 0; i < Integer.MAX_VALUE; i++)
			obj[i] = i;

		System.out.println("I am done");
	}

}

 

Compile and run the above program.

$javac OutOfMemoryErrorDemo.java 
$
$java OutOfMemoryErrorDemo
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
	at OutOfMemoryErrorDemo.main(OutOfMemoryErrorDemo.java:4)

 

How to address the OutOfMemoryError?

a. First Profile your application and try to figure out, is your application referring any unused objects, or is there any memory leaks etc., You can refer this post to find the tools to analyze your java application.

 

b. Increase the heap size. Refer this post for more details.

 

 

References

https://docs.oracle.com/javase/7/docs/api/java/lang/StackOverflowError.html

https://docs.oracle.com/javase/7/docs/api/java/lang/OutOfMemoryError.html

 

 

 You may like

Interview Questions

Implement map using array as storage

How to resolve NoClassDefFoundError?

Jagged arrays in Java

Get the length of longest row in a two dimensional jagged array in Java

Quick guide to OutOfMemoryError in Java