Проверка JSON не выполняется во время выполнения, даже если тесты пройдены - PullRequest
0 голосов
/ 21 декабря 2018

Я использую популярную библиотеку схем JSON - json-schema-validator - для проверки входящих полезных данных по моей собственной схеме.

Ниже приводится краткое изложение моей скорби:

private final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
    private JsonSchema preparedSchema;
    public ReportByTeamCriteriaSchemaChecker(String schemaLocationPath) {
        try {
            JsonNode schemaNode = JsonLoader.fromPath(schemaLocationPath);
            this.preparedSchema = this.factory.getJsonSchema(schemaNode);
        } catch (ProcessingException | IOException e) {
            e.printStackTrace();
        }
    }

Никаких проблем пока нет.Файл схемы находится в назначенном месте, и готовится schemaNode.

Учитывая входящую JSONString (полезную нагрузку, чтобы быть более определенной), вот как я подтверждаю ее правильность по отношению к схеме, загруженной ранее:

private Try<ProcessingReport>  checkAgainstSchema(JsonSchema schema, String jsonifiedString) {

   Try<ProcessingReport> result =
      Try
      .of(() ->  JsonLoader.fromString(jsonifiedString))
      .mapTry( (jsonNode) -> schema.validate(jsonNode));

        return (result);
    }

Эта функция вызывается так:

Try<String> syntaxParsingresult =
     this.checkAgainstSchema(this.preparedSchema, jsonifiedString)
    .map(e -> extractErrorMessagesFromReport(e));

Соответствующая часть build.gradle файла:

sourceCompatibility = '1.9'
targetCompatibility = '1.9'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

if (!hasProperty('mainClass')) {
    //ext.mainClass = 'test.NewMain'
    mainClassName = "drivers.ReportServerEntryPoint"
}

repositories {
    mavenCentral()
    maven { url "http://maven.restlet.org" }
}
ext.restletVersion = "2.3.10"

// ........

 // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
    // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.8'
    // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.8'
    // https://mvnrepository.com/artifact/commons-io/commons-io
    compile group: 'commons-io', name: 'commons-io', version: '2.6'
    compile(group: "com.github.java-json-tools", name: "json-schema-validator", version: "2.2.10")
    // https://mvnrepository.com/artifact/io.vavr/vavr
    compile group: 'io.vavr', name: 'vavr', version: '0.9.2'

Thisотлично работает отлично (включая все тестовые случаи) при запуске из внутри IntelliJ IDEA .Однако, когда я собираю JAR и запускаю из командной строки , выбрасываемое исключение очень сбивает с толку:

enter image description here

Источниклиния, которая считается оскорбительной для JVM (ReportByTeamCriteriaSchemaChecker.java:59), соответствует вызову функции, упомянутому ранее:

schema.validate (jsonNode)

Яиспользуя vavr - и поэтому я изначально подозревал, что vavr и json-schema-validator и Джексону было неудобно находиться вместе - но я подтвердил, что даже если я не использую Try vavr, исключение выдается во время выполнения.

Я упомянул этот разговор о StackOverflow, но он мне мало пригоден.

Я использую JDK 1.9:

java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

Может ли кто-нибудь, знакомый с JSON Validation, указать мне правильное направление?


Обновление :

В качестве эксперимента я добавил следующее в зависимости:

    dependencies {
      compile(group: "com.github.fge", name: "jackson-coreutils", version: "1.8");
    }

В этом случае, когда я запускаю JAR из командной строки, сообщение об ошибке точно переворачивается:

Caused by: java.lang.IncompatibleClassChangeError: Found interface com.github.fge.jsonschema.main.JsonSchema, but class was expected
    at com.oneHuddle.application.utility.schemaChecker.ReportByTeamCriteriaSchemaChecker.validateAgainstSchema(ReportByTeamCriteriaSchemaChecker.java:59)
    at com.oneHuddle.application.ReportByTeamResource.lambda$getDefaultTeamReport$0(ReportByTeamResource.java:60)
    at io.vavr.control.Either.flatMap(Either.java:331)
    at com.oneHuddle.application.ReportByTeamResource.getDefaultTeamReport(ReportByTeamResource.java:59)

Если что-то, я более запутался!:-) Почему он должен нормально работать изнутри IntelliJ , но выдает эту ошибку, когда исполняемый JAR запускается из командной строки ?

1 Ответ

0 голосов
/ 21 декабря 2018

Обратившись к следующему классу,

com.github.fge.jsonschema.main.JsonValidator

Я смог обойти проблему.

Текущий код выглядит следующим образом:

private final JsonValidator validator = 
    JsonSchemaFactory.byDefault().getValidator();
private  JsonNode   schemaNode;
public ReportByTeamCriteriaSchemaChecker(String schemaLocationPath) {
    try {
        this.schemaNode = JsonLoader.fromPath(schemaLocationPath);
    } catch (IOException e) {
         e.printStackTrace();
    }
}

Функция, которая ранее использовала схему, теперь использует вместо нее валидатор:

private Try<ProcessingReport>  
validatePayload(
     JsonNode schemaNode, String payload) {

   Try<ProcessingReport> result =
      Try
      .of(()->  JsonLoader.fromString(payload))
      .mapTry((jsonNode)  ->  
             this.validator.validate(schemaNode,jsonNode));

   return (result);

}

Управляющая функция ведет себя так же, как и в предыдущем аватаре:

 public Either<Tuple2<Enum<ReportByTeamExecutionStatus>,String>,String>
    validateAgainstSchema(String jsonifiedString) {

       Try<String> syntaxParsingresult =
               this.validateAgainstSchema(this.schemaNode, jsonifiedString)
               .map(e -> extractErrorMessagesFromReport(e));
// ..... rest of the logic

Я экспериментировал с 3-4 возможностями, в том числе:

  • принудительное обновление всех зависимостей
  • создание отчета о сканировании gradle
  • игра с несколькимиразличные версии Джексона и других зависимых библиотек

, но ни одна из них не работала, но эта работала.

Просто чтобы уточнить, я не выяснил, в чем именно заключалась разница между IntelliJview of runtimeclasspath и команда gradle.Очевидно, что они разрешают зависимости слегка (или не очень) разными способами.Но у меня не было времени.

Я думал, что должен опубликовать свое решение, на случай, если оно кому-нибудь поможет.

...