使用JBoss(6.2.0 GA)在EJB Jar中忽略了Jackson 2注释 [英] Jackson 2 annotations ignored in EJB Jar with JBoss (6.2.0 GA)

查看:111
本文介绍了使用JBoss(6.2.0 GA)在EJB Jar中忽略了Jackson 2注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Web应用程序从Websphere 7(JEE5)迁移到JBoss EAP 6.2.0(JEE6)。它目前在Glassfish 3& WAS。

I am migrating a web app from Websphere 7 (JEE5) to JBoss EAP 6.2.0 (JEE6). It currently works fine in Glassfish 3 & WAS.

Web界面消耗/生成JSON - 所以我使用Jackson2和Spring 3 MVC MappingJackson2HttpMessageConverter 来处理(de)简单控制器类中的序列化。

The web interface consumes/produces JSON - so am using Jackson2 with Spring 3 MVC MappingJackson2HttpMessageConverter to handling (de)serialisation in a simple controller class.

在JBoss中我看到在ejb模块中忽略了Jackson2注释 @JsonProperty 等 - (它们仅适用于JPA实体),但 正在网络模块中应用。因此,对于JBoss中的某些对象,响应会返回不同的字段名称,这会使我们的用户界面瘫痪。

In JBoss I see Jackson2 annotations @JsonProperty etc are being ignored in the ejb module - (they are applied to JPA entities only), but are being applied in the web module. So responses come back with different field names for some objects in JBoss which trips up our user interface.

我已经尝试了每个 jboss- deployment-structure.xml 无济于事(见下文)。我知道JBoss将Jackson 1.x作为内部模块。但是,这似乎不是问题,否则Web模块注释也会被忽略?例如:部署到JBOSS后忽略了Jackson注释

I've tried every permuation of jboss-deployment-structure.xml to no avail (see below). I'm aware that JBoss ships with Jackson 1.x as an internal module. However, this doesn't seem to be the problem, otherwise the web module annotations would be ignored as well ? E.g.: Jackson annotations ignored after deployment to JBOSS

该应用程序的结构为3个maven模块 - war,ejb(jar)&耳塞。

The app is structured as 3 maven modules - war, ejb (jar) & the ear container.

我将重构代码以从JPA实体中删除注释,但实际上找到一个连贯的解决方案会很好,因为还有其他几个应用程序迁移。

I'm going to refactor the code to remove the annotations from the JPA entities, but really it would be good to find a coherent solution, as there are several other apps to migrate.

<jboss-deployment-structure>
    <ear-subdeployments-isolated>false</ear-subdeployments-isolated>
    <deployment>
        <exclusions>
            <module name="org.codehaus.jackson.jackson-core-asl"/>
            <module name="org.codehaus.jackson.jackson-mapper-asl"/>
        </exclusions>
    </deployment>
    <sub-deployment name="my-war.war">
        <exclusions>
            <module name="org.codehaus.jackson.jackson-core-asl"/>
            <module name="org.codehaus.jackson.jackson-mapper-asl"/>
        </exclusions>
    </sub-deployment>
    <sub-deployment name="my-ejbs.jar">
        <exclusions>
            <module name="org.codehaus.jackson.jackson-core-asl"/>
            <module name="org.codehaus.jackson.jackson-mapper-asl"/>
        </exclusions>
    </sub-deployment>
</jboss-deployment-structure>



初步解决方法(现已恢复)



虽然它没有解决原始问题的原因,但我已经通过在Web模块中添加Jackson Mixin来重新命名/禁止相关字段来解决这个问题。我测试了这个并且它工作正常。

Initial Workaround (reverted now)

Whilst it does not address what the original problem was caused by, I have solved this by adding a Jackson Mixin within the web module to rename/suppress the fields concerned. I've tested this and it works fine.

关于这一切的一点是,通过使用Jackson Mixin,序列化定制的范围受到限制到Web模块,从而避免了由于 ejb-jar 子部署导致的类加载问题。没有使用 jboss-deployment-structure.xml

The point about all this, is that by using a Jackson Mixin, the scope of the customisation of the serialisation has been confined to the web module, and thereby avoided possible class loading issues due to ejb-jar sub-deployment. No jboss-deployment-structure.xml is being used.

添加一个Mixin

public interface MyMixin {


    @JsonIgnore
    String getUnwantedField();

    @JsonProperty(value = "newName")
    String getOldName();

}

然后在我的网络控制器启动时我接通了混合到Jackson ObjectMapper,它自动装入控制器并在我的调度程序servlet xml config中定义。

Then in the startup of my web controller I wire in the Mixin to the Jackson ObjectMapper which is autowired into the controller and defined in my dispatcher servlet xml config.

 @Autowired
 private ObjectMapper objectMapper;

 @PostConstruct
    void configObjectMapper() {
        objectMapper.addMixInAnnotations(MyEjbJar.class, MyMixin.class);     
    }

Dispatcher servlet:

Dispatcher servlet:

.
.
    <bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>


推荐答案

我已经跟踪了这一点(通过IDE调试器&添加日志记录)到用于war模块和ejb jar模块的不同类加载器。根据文档,这是JBoss AS 7的预期默认行为。战争使用 war ModuleLoader,ejb jar使用 ear ModuleLoader。

I have tracked this down (via IDE debugger & adding logging) to different classloaders being used for the war module and ejb jar module. This is expected default behaviour with JBoss AS 7 according to the docs. The war uses the war ModuleLoader, and the ejb jar uses the ear ModuleLoader.

注释的Class会根据哪个类加载器加载注释而有所不同。另请参阅:类似问题所以

What happens is the Class for the annotation differs depending on which class loader loads the annotation. Also see: similar issue on SO

不同我的意思是它们是相同的注释,来源于同一个jar&版本,但根据equals的合同,它们不等同,它们的哈希码不同,因此 JacksonAnnotationIntrospector 不会找到注释,即使它们显示为对JPA POJO类持有。

By "differs" I mean they are the same annotation, sourced from the same jar & version, but they are not deemed equivalent according to the contract for equals, their hashcodes differ, therefore the JacksonAnnotationIntrospector does not locate annotations even though they show as held against the JPA POJO class.

我已经解决了这个问题,因为将ModuleLoader作为jackson 2的常用加载程序。我这样做是通过制作 com.fasterxml.jackson.core databind 依赖提供战争范围& ejb jar,并将其标记为耳朵POM中的正常编译范围依赖项。

I have worked around this by making the ear ModuleLoader be a common loader for jackson 2. I did this by making the com.fasterxml.jackson.core databind dependency provided scope in the war & ejb jar, and marking it as a normal compile scope dependency in the ear POM.

这种方法在这里得到了认可 JBoss AS类加载虽然它使用 jboss-deployment-structure 或MANIFEST.MF来实现几乎相同的东西。

This kind of approach is sort of endorsed here JBoss AS classloading although it uses the jboss-deployment-structure or MANIFEST.MF to achieve pretty much the same thing.

这篇关于使用JBoss(6.2.0 GA)在EJB Jar中忽略了Jackson 2注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆