All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cedarsoftware.io.factory.StackTraceElementFactory Maven / Gradle / Ivy

There is a newer version: 4.9.8
Show newest version
package com.cedarsoftware.io.factory;

import java.lang.reflect.Constructor;

import com.cedarsoftware.io.JsonObject;
import com.cedarsoftware.io.JsonReader;
import com.cedarsoftware.io.Resolver;
import com.cedarsoftware.util.ExceptionUtilities;
import com.cedarsoftware.util.ReflectionUtils;

/**
 * Factory class to create Throwable instances.  Needed for JDK17+ as the only way to set the
 * 'detailMessage' field on a Throwable is via its constructor.
 * 

* * @author Kenny Partlow ([email protected]) *
* Copyright (c) Cedar Software LLC *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* License *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ public class StackTraceElementFactory implements JsonReader.ClassFactory { public static final String DECLARING_CLASS = "declaringClass"; public static final String METHOD_NAME = "methodName"; public static final String FILE_NAME = "fileName"; public static final String LINE_NUMBER = "lineNumber"; public static final String CLASS_LOADER_NAME = "classLoaderName"; public static final String MODULE_NAME = "moduleName"; public static final String MODULE_VERSION = "moduleVersion"; /** * JDK 9+ introduced a new 7-arg constructor: * StackTraceElement(String classLoaderName, * String moduleName, * String moduleVersion, * String declaringClass, * String methodName, * String fileName, * int lineNumber) * If this exists (constructor2 != null), we can use it. */ private static final Constructor constructor1; // the 4-arg constructor private static final Constructor constructor2; // the 7-arg constructor static { // Use ReflectionUtils for caching: // getConstructor(klass, paramTypes...) returns null if not found, caching the miss. // 4-arg version: StackTraceElement(String declaringClass, String methodName, String fileName, int lineNumber) constructor1 = ReflectionUtils.getConstructor( StackTraceElement.class, String.class, String.class, String.class, int.class ); // 7-arg version: StackTraceElement(String loader, String module, String version, String declaringClass, ...) constructor2 = ReflectionUtils.getConstructor( StackTraceElement.class, String.class, String.class, String.class, String.class, String.class, String.class, int.class ); } @Override public Object newInstance(Class c, JsonObject jObj, Resolver resolver) { // Pull fields from the JSON map String declaringClass = (String) jObj.get(DECLARING_CLASS); String methodName = (String) jObj.get(METHOD_NAME); String fileName = (String) jObj.get(FILE_NAME); Number lineNum = (Number) jObj.get(LINE_NUMBER); String classLoaderName = (String) jObj.get(CLASS_LOADER_NAME); String moduleName = (String) jObj.get(MODULE_NAME); String moduleVersion = (String) jObj.get(MODULE_VERSION); // Attempt to call the 7-arg constructor if available if (constructor2 != null) { StackTraceElement element = ExceptionUtilities.safelyIgnoreException( () -> (StackTraceElement) constructor2.newInstance( classLoaderName, moduleName, moduleVersion, declaringClass, methodName, fileName, lineNum.intValue() ), null ); if (element != null) { return element; } } // Otherwise, try the 4-arg constructor if (constructor1 != null) { StackTraceElement element = ExceptionUtilities.safelyIgnoreException( () -> (StackTraceElement) constructor1.newInstance( declaringClass, methodName, fileName, lineNum.intValue() ), null ); if (element != null) { return element; } } // Fallback: If reflection-based calls failed, build one directly return new StackTraceElement( declaringClass, methodName, fileName, lineNum == null ? -1 : lineNum.intValue() ); } @Override public boolean isObjectFinal() { return true; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy