Showing posts with label exception. Show all posts
Showing posts with label exception. Show all posts

Wednesday, 3 May 2023

Convert a throwable or an exception stack trace to string in Java

Following snippet converts the exception or a throwable stack trace to string representation.

public static String throwableToString(Throwable t) {

	try (StringWriter stringWriter = new StringWriter(); PrintWriter pw = new PrintWriter(stringWriter, true);) {
		t.printStackTrace(pw);
		pw.flush();
		return stringWriter.toString();
	} catch (IOException e) {
		e.printStackTrace(System.err);
		return "Error occurred : " + e.getMessage();
	}
}

 

Find the below working application.


 

ThrowableToString.java
package com.sample.app.strings;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class ThrowableToString {

	public static String throwableToString(Throwable t) {

		try (StringWriter stringWriter = new StringWriter(); PrintWriter pw = new PrintWriter(stringWriter, true);) {
			t.printStackTrace(pw);
			pw.flush();
			return stringWriter.toString();
		} catch (IOException e) {
			e.printStackTrace(System.err);
			return "Error occurred : " + e.getMessage();
		}
	}

	public static void main(String[] args) {
		try {
			int result = 10 / 0;
			System.out.println(result);
		} catch (Throwable t) {
			System.out.println(throwableToString(t));
		}
	}

}

 

Output

java.lang.ArithmeticException: / by zero
	at com.sample.app.strings.ThrowableToString.main(ThrowableToString.java:23)

 

  

Previous                                                 Next                                                 Home

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?