12

JSON入力 Pojo インスタンスを取得する必要があり、Jackson 2ライブラリを使用しており、以下のreadValueメソッドは typeReferencing を使用して逆シリアル化できます。

POJO_ClassName p = mapper.readValue(new TypeReference< POJO_ClassName >() {});

しかし、問題は、POJO実行時に動的に作成およびロードされるため、上記のステートメントの完全修飾クラス (POJO_ClassName) 名がないため、どうすればインスタンス/オブジェクトにアクセスできるかということですJSONPOJO

注:jsonSchema2pojoライブラリを使用POJOして、実行時にクラスを生成します。

ここにコードスニペットがあります。実行時に生成するPOJOために使用しJSON 、試しています

  String classPath="com.EnrichmentService.Thread72"; 
     String classLocation = System.getProperty("user.dir")
                         + "/src/main/java"; JCodeModel codeModel = new JCodeModel();

     final RuleFactory ruleFactory = new RuleFactory(config,
                         new Jackson2Annotator(config), new SchemaStore());

     final SchemaMapper mapperSchema = new SchemaMapper(ruleFactory,
                         new SchemaGenerator());

     mapperSchema.generate(codeModel, "EsRootDoc",classPath, json);

     codeModel.build(new File(classLocation));  // generates pojo classes

     // Till above jsonSchema2Pojo pojo generation all Good !!
      // EsRootDoc instance is needed for further drools drl validations.

     com.EnrichmentService.Thread72.EsRootDoc p = mapper.readValue(new TypeReference<com.EnrichmentService.Thread72.EsRootDoc>() {}); 
// see alternative way as well in my 24Aug17 edit at the end of this question

しかし、com.EnrichmentService.Thread72.EsRootDocまだ生成されていないため、コンパイラはクラスが見つかりませんでした。

主なポイント:

1) 実行時に同じ Pojo クラスが繰り返し生成されますが、JSON 入力が毎回変化するため、プロパティが異なります。

2) Object pojo =mapper.readValue(json,Class.forName("com.EnrichmentService.Thread72.EsRootDoc")); も試しました class.forName は既存のクラスを置き換えません!

編集 24 Aug17 - これが私のカスタムクラスローダーです:

注: インデクサーは、実行時に動的な EsRootDoc/POJO クラスをロードするクラスです。

 static class TestClassLoader extends ClassLoader {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                if (name.equals("com.EnrichmentService.Thread72.EsRootDoc")) {
                    try {
                        InputStream is = Indexer.class.getClassLoader().getResourceAsStream("com/EnrichmentService/Thread72/EsRootDoc.class");
                        byte[] buf = new byte[is.available()];
                        int len = is.read(buf);

                        Class<?> c=defineClass(name, buf, 0, len);
                        resolveClass(c);
                        return c;


                    } catch (IOException e) {
                        throw new ClassNotFoundException("", e);
                    }
                }
                return getParent().loadClass(name);
            }
        }

別の方法として、上記の TestClassLoader カスタム クラス ローダーを使用してみましたが、次のようになります。

Class cls = new      TestClassLoader().loadClass("com.EnrichmentService.Thread72.EsRootDoc");
    Object obj = cls.newInstance();
    cls.getMethod("getCrawlerSource").invoke(obj);
    p=mapper.readValue(json, cls);  // but here i am getting the same deserialization exception as earlier.

古い回答を参照 @ How to replace classes in a running application in java ?

Edit2: 24Aug17 例外が直面している stackTrace はこちら: https://pastebin.com/ckCu2uWx

4

3 に答える 3