1

I deployed my application war to tomcat, threw StackOverflowError after startup, the stacktrace is shown in the picture below. stacktrace

According to the stacktrace tip and source code, i can find the cyclic inheritance dependencies are: org.bouncycastle.asn1.ASN1Boolean extends org.bouncycastle.asn1.DERBoolean(org.bouncycastle:bcprov-jdk15:1.45) org.bouncycastle.asn1.DERBoolean extends org.bouncycastle.asn1.ASN1Boolean(org.bouncycastle:bcprov-jdk15on:1.60)

key source code:

    protected void checkHandlesTypes(JavaClass javaClass,
            Map<String,JavaClassCacheEntry> javaClassCache) {

        // ....

        String className = javaClass.getClassName();

        Class<?> clazz = null;
        if (handlesTypesNonAnnotations) {
            populateJavaClassCache(className, javaClass, javaClassCache);
            JavaClassCacheEntry entry = javaClassCache.get(className);
            if (entry.getSciSet() == null) {
                try {           
                    // soe throws because of this code(recursive call)
                    populateSCIsForCacheEntry(entry, javaClassCache);
                } catch (StackOverflowError soe) {
                    throw new IllegalStateException(sm.getString(
                            "contextConfig.annotationsStackOverflow",
                            context.getName(),
                            classHierarchyToString(className, entry, javaClassCache)));
                }
            }            
        }
    }

    private void populateJavaClassCache(String className, JavaClass javaClass,
            Map<String,JavaClassCacheEntry> javaClassCache) {
        if (javaClassCache.containsKey(className)) {
            return;
        }

        // Add this class to the cache
        javaClassCache.put(className, new JavaClassCacheEntry(javaClass));

        populateJavaClassCache(javaClass.getSuperclassName(), javaClassCache);

        for (String interfaceName : javaClass.getInterfaceNames()) {
            populateJavaClassCache(interfaceName, javaClassCache);
        }
    }

    private void populateJavaClassCache(String className,
            Map<String,JavaClassCacheEntry> javaClassCache) {
        if (!javaClassCache.containsKey(className)) {
            String name = className.replace('.', '/') + ".class";
            try (InputStream is = context.getLoader().getClassLoader().getResourceAsStream(name)) {
                if (is == null) {
                    return;
                }
                ClassParser parser = new ClassParser(is);
                JavaClass clazz = parser.parse();
                populateJavaClassCache(clazz.getClassName(), clazz, javaClassCache);
            } catch (ClassFormatException e) {
                log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
                        className), e);
            } catch (IOException e) {
                log.debug(sm.getString("contextConfig.invalidSciHandlesTypes",
                        className), e);
            }
        }
    }

---------------edits--------------

I’ve known how to fix the error,my point is how the recursive call happen in populateSCIsForCacheEntry method.

I read the populateJavaClassCache method,after the org.bouncycastle:bcprov-jdk15:1.45 jar parsed,the javaCacheMap contains: "org.bouncycastle.asn1.ASN1Boolean" -> classEntry["org.bouncycastle.asn1. DERBoolean","interface stuff"], "org.bouncycastle.asn1.DERBoolean" -> classEntry["Java.lang.Object","interface stuff"],

and when org.bouncycastle:bcprov-jdk15on:1.60 jar is parsing,keys for class org.bouncycastle.asn1.ASN1Boolean and org.bouncycastle.asn1.DERBoolean won't be put into javaCacheMap again because of map's contains method check.

so the javaCacheMap does not contain the cyclic dependencies below: "org.bouncycastle.asn1.ASN1Boolean" -> classEntry["org.bouncycastle.asn1. DERBoolean","interface stuff"], "org.bouncycastle.asn1.DERBoolean" -> classEntry["org.bouncycastle.asn1.ASN1Boolean","interface stuff"],

and how does the recursive call happen?

Jadic
  • 33
  • 1
  • 7
  • Does this answer your question? [Unable to complete the scan for annotations for web application \[/app\] due to a StackOverflowError](https://stackoverflow.com/questions/17584495/unable-to-complete-the-scan-for-annotations-for-web-application-app-due-to-a) – Piotr P. Karwasz Aug 23 '21 at 13:38
  • You have both an old (version 1.46 or lower) and new (version 1.47 or higher) version of BouncyCastle on your classpath. – Piotr P. Karwasz Aug 23 '21 at 13:53
  • 1
    @Piotr i know how to fix it, plz read my edit – Jadic Aug 24 '21 at 00:03

0 Answers0