Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checker framework crashes, how do I prevent the crash? #6378

Closed
spacether opened this issue Dec 19, 2023 · 1 comment
Closed

Checker framework crashes, how do I prevent the crash? #6378

spacether opened this issue Dec 19, 2023 · 1 comment

Comments

@spacether
Copy link

spacether commented Dec 19, 2023

Thanks for submitting an issue.
As explained in the instructions for submitting an issue at https://checkerframework.org/manual/#reporting-bugs, please include four pieces of information:

  • commands (that can be cut-and-pasted into a command shell),
  • inputs,
  • outputs, and
  • expectation.

I have four adjacent classes

  • JsonSchema.java
  • PathToSchemasMap.java
  • ValidationMetaData.java
  • TypeValidator.java

When I build the project it crashes the checker framework.
Here are the java files:
JsonSchema.java

package org.openapijsonschematools.client.schemas.validation;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public abstract class JsonSchema {
    public final @Nullable Set<Class<?>> type;
    private final @NonNull LinkedHashMap<String, TypeValidator> keywordToValidator;

    protected JsonSchema(@Nullable Set<Class<?>> type) {
        LinkedHashMap<String, TypeValidator> keywordToValidator = new LinkedHashMap<>();
        this.type = type;
        if (this.type != null) {
            keywordToValidator.put(
                    "type",
                    new TypeValidator(this.type)
            );
        }
        this.keywordToValidator = keywordToValidator;
    }

    public static PathToSchemasMap validate(
            JsonSchema jsonSchema,
            Object arg,
            ValidationMetadata validationMetadata
    ) {
        LinkedHashSet<String> disabledKeywords = validationMetadata.configuration().disabledKeywordFlags().getKeywords();
        PathToSchemasMap pathToSchemas = new PathToSchemasMap();
        LinkedHashMap<String, TypeValidator> thisKeywordToValidator = jsonSchema.keywordToValidator;
        if (thisKeywordToValidator != null) {
            for (Map.Entry<String, TypeValidator> entry: thisKeywordToValidator.entrySet()) {
                String jsonKeyword = entry.getKey();
                if (disabledKeywords.contains(jsonKeyword)) {
                   continue;
                }
                TypeValidator validator = entry.getValue();
                PathToSchemasMap otherPathToSchemas = validator.validate(
                        jsonSchema,
                        arg,
                        validationMetadata
                );
                if (otherPathToSchemas == null) {
                    continue;
                }
                pathToSchemas.update(otherPathToSchemas);
            }
        }
        List<Object> pathToItem = validationMetadata.pathToItem();
        if (!pathToSchemas.containsKey(pathToItem)) {
            pathToSchemas.put(validationMetadata.pathToItem(), new LinkedHashMap<>());
        }
        pathToSchemas.get(pathToItem).put(jsonSchema, null);

        return pathToSchemas;
    }
}

PathToSchemasMap.java

package org.openapijsonschematools.client.schemas.validation;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class PathToSchemasMap extends LinkedHashMap<List<Object>, LinkedHashMap<JsonSchema, Void>> {

    public void update(PathToSchemasMap other) {
        for (Map.Entry<List<Object>, LinkedHashMap<JsonSchema, Void>> entry: other.entrySet()) {
            List<Object> pathToItem = entry.getKey();
            LinkedHashMap<JsonSchema, Void> otherSchemas = entry.getValue();
            if (containsKey(pathToItem)) {
                get(pathToItem).putAll(otherSchemas);
            } else {
                put(pathToItem, otherSchemas);
            }
        }
    }
}

ValidationMetadata.java

package org.openapijsonschematools.client.schemas.validation;

import org.openapijsonschematools.client.configurations.SchemaConfiguration;
import java.util.List;
import java.util.Map;
import java.util.Set;

public record ValidationMetadata(
        List<Object> pathToItem,
        SchemaConfiguration configuration,
        PathToSchemasMap validatedPathToSchemas,
        Set<Class<?>> seenClasses
) {

    public boolean validationRanEarlier(JsonSchema schema) {
        Map<JsonSchema, Void> validatedSchemas = validatedPathToSchemas.getOrDefault(pathToItem, null);
        if (validatedSchemas != null && validatedSchemas.containsKey(schema)) {
            return true;
        }
        if (seenClasses.contains(schema)) {
            return true;
        }
        return false;
    }
}

TypeValidator.java

package org.openapijsonschematools.client.schemas.validation;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.openapijsonschematools.client.exceptions.ValidationException;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class TypeValidator {
    public final Set<Class<?>> type;

    public TypeValidator(Set<Class<?>> type) {
        this.type = type;
    }

    public @Nullable PathToSchemasMap validate(JsonSchema schema, Object arg, ValidationMetadata validationMetadata) {
        Class<?> argClass;
        if (arg == null) {
            argClass = Void.class;
        } else if (arg instanceof List) {
            argClass = List.class;
        } else if (arg instanceof Map) {
            argClass = Map.class;
        } else {
            argClass = arg.getClass();
        }
        if (!type.contains(argClass)) {
            throw new ValidationException("invalid type");
        }
        return null;
    }
}

And my relevant configuration info from pom.xml is here:

    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <defaultGoal>install</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <fork>true</fork>
                    <meminitial>128m</meminitial>
                    <maxmem>512m</maxmem>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <compilerArgs combine.children="append">
                        <arg>-Awarns</arg>
                        <arg>-J-Xss4m</arg><!-- Compiling the generated JSON.java file may require larger stack size. -->
                        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
                        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
                        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
                        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
                        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
                        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
                        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
                        <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
                        <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
                    </compilerArgs>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.checkerframework</groupId>
                            <artifactId>checker</artifactId>
                            <version>${checker-version}</version>
                        </path>
                    </annotationProcessorPaths>
                    <annotationProcessors>
                        <annotationProcessor>
                            org.checkerframework.checker.nullness.NullnessChecker
                        </annotationProcessor>
                    </annotationProcessors>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.checkerframework</groupId>
            <artifactId>checker-qual</artifactId>
            <version>${checker-version}</version>
        </dependency>
        <dependency>
            <groupId>org.checkerframework</groupId>
            <artifactId>checker</artifactId>
            <version>${checker-version}</version>
        </dependency>
    </dependencies>
    <properties>
        <checker-version>3.33.0</checker-version>
    </properties>

And I run mvn package and I get this error:

java: SourceChecker.typeProcess: unexpected Throwable (NoSuchMethodError) while processing /Users/justinblack/programming/openapi-json-schema-generator/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PathToSchemasMap.java; message: 'com.sun.tools.javac.tree.JCTree$JCExpression com.sun.tools.javac.tree.TreeMaker.Select(com.sun.tools.javac.tree.JCTree$JCExpression, com.sun.tools.javac.code.Symbol)'
  ; The Checker Framework crashed.  Please report the crash.
  Compilation unit: /Users/justinblack/programming/openapi-json-schema-generator/samples/client/3_0_3_unit_test/java/src/main/java/org/openapijsonschematools/client/schemas/validation/PathToSchemasMap.java
  Last visited tree at line 7 column 1:
  public class PathToSchemasMap extends LinkedHashMap<List<Object>, LinkedHashMap<JsonSchema, Void>> {
  Exception: java.lang.NoSuchMethodError: 'com.sun.tools.javac.tree.JCTree$JCExpression com.sun.tools.javac.tree.TreeMaker.Select(com.sun.tools.javac.tree.JCTree$JCExpression, com.sun.tools.javac.code.Symbol)'; java.lang.NoSuchMethodError: 'com.sun.tools.javac.tree.JCTree$JCExpression com.sun.tools.javac.tree.TreeMaker.Select(com.sun.tools.javac.tree.JCTree$JCExpression, com.sun.tools.javac.code.Symbol)'
  	at org.checkerframework.javacutil.trees.TreeBuilder.buildIteratorMethodAccess(TreeBuilder.java:122)
  	at org.checkerframework.dataflow.cfg.builder.CFGTranslationPhaseOne.visitEnhancedForLoop(CFGTranslationPhaseOne.java:2820)

Why is the type checker framework crashing?
How do I eliminate this crash?

I expect the framework not to crash as the code compiles.
This came up in this PR: openapi-json-schema-tools/openapi-json-schema-generator#340

I am using:
IntelliJ IDEA 2023.2.5 (Community Edition)
Java 17

@spacether spacether changed the title Checker framework crashes, how do prevent the crash? Checker framework crashes, how do I prevent the crash? Dec 19, 2023
@spacether
Copy link
Author

spacether commented Dec 19, 2023

Never mind. This error happened because I was incorrectly using java 21 when I should have been using java 17
It went away when using the correct java version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant