ClassCastException DTO OSGI

ClassCastException DTO OSGI

我有三个蓝图包(不同的 jar):

意识到这些包构成了模块游戏的层。场景:

问题:

GameServiceImpl中的Gametypedap-service包加载class加载器和由 IGameDAO 服务 return 编辑的实例属于另一种类型,因为它们是由 ap-dao 包 class 加载的加载程序,因此生成 ClassCastException。意识到 class 是相同的 (app.Game.java) ,应该是 DTO。 DTO 是基本的 objects,我必须能够使用它们并通过捆绑包(通过服务)传递它们。 OSGI 中如何处理 DTO?我该如何解决这个问题?

// code in GameServiceImpl, from ap-service bundle
public void prettyPrintGames() {
    List<Game> games = gameDao().findAll();

    /* ClassCastException in the for-loop, since the type Game, in ap-service
     * is not the same of the instances of varible 'games', 
     * returned by the DAO service instance. This is the reason
     * of the classloader issue.
     */
    for(Game g : games){
        System.out.println(g.toString()); 
    }
}

结构:

ap-data

+---ap-data
|   |   pom.xml
|   |       
|   +---src
|   |   \---main
|   |       +---java
|   |       |   \---br
|   |       |       \---com
|   |       |           \---company
|   |       |               \---game
|   |       |                   \---entity
|   |       |                           Game.java

捆绑清单:

Manifest-Version: 1.0
Bnd-LastModified: 1445945039034
Build-Jdk: 1.7.0_07
Built-By: user
Bundle-Description: ap-data
Bundle-ManifestVersion: 2
Bundle-Name: ap-data
Bundle-SymbolicName: ap-data
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Export-Package: br.com.company.game.entity;version="1.0.0";uses:="javax.
 persistence"
Import-Package: javax.persistence;version="[2.1,3)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"
Tool: Bnd-3.0.0.201509101326

ap-dao

+---ap-dao
|   |   pom.xml
|   +---src
|   |   \---main
|   |       +---java
|   |       |   \---br
|   |       |       \---com
|   |       |           \---company
|   |       |               \---game
|   |       |                   \---dao
|   |       |                       +---api
|   |       |                       |       IGameDAO.java
|   |       |                       |       
|   |       |                       \---impl
|   |       |                               GameDAOImpl.java
|   |       |                               
|   |       \---resources
|   |           +---META-INF
|   |           |       persistence.xml
|   |           |       
|   |           \---OSGI-INF
|   |               \---blueprint
|   |                       blueprint.xml
|   |                       

捆绑清单

Manifest-Version: 1.0
Bnd-LastModified: 1445945039855
Build-Jdk: 1.7.0_07
Built-By: user
Bundle-Blueprint: OSGI-INF/blueprint/blueprint.xml
Bundle-Description: game-module
Bundle-ManifestVersion: 2
Bundle-Name: ap-dao
Bundle-SymbolicName: ap-dao
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Export-Package: br.com.company.game.dao.api;version="1.0.0";uses:="br.co
 m.company.game.entity"
Export-Service: br.com.company.game.dao.api.IGameDAO
Import-Package: br.com.company.game.dao.api;version="[1.0,2)",br.com.com
 pany.game.entity;version="[1.0,2)",javax.persistence;version="[2.1,3)",
 org.osgi.service.blueprint;version="[1.0.0,2.0.0)"
Meta-Persistence: META-INF/persistence.xml
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"
Tool: Bnd-3.0.0.201509101326

ap-service

+---ap-service
|   |   pom.xml
|   |   
|   +---src
|   |   \---main
|   |       +---java
|   |       |   \---br
|   |       |       \---com
|   |       |           \---company
|   |       |               \---game
|   |       |                   \---service
|   |       |                       +---api
|   |       |                       |       IGameService.java
|   |       |                       |       
|   |       |                       \---impl
|   |       |                               GameServiceImpl.java
|   |       |                               
|   |       \---resources
|   |           \---OSGI-INF
|   |               \---blueprint
|   |                       service.xml
|   |                       

捆绑清单

Manifest-Version: 1.0
Bnd-LastModified: 1445945040469
Build-Jdk: 1.7.0_07
Built-By: user
Bundle-Blueprint: OSGI-INF/blueprint/service.xml
Bundle-Description: game-module
Bundle-ManifestVersion: 2
Bundle-Name: ap-service
Bundle-SymbolicName: ap-service
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Export-Package: br.com.company.game.service.api;version="1.0.0"
Export-Service: br.com.company.game.service.api.IGameService
Import-Package: br.com.company.game.dao.api;version="[1.0,2)",br.com.com
 pany.game.entity;version="[1.0,2)",br.com.company.game.service.api;vers
 ion="[1.0,2)",org.osgi.service.blueprint;version="[1.0.0,2.0.0)"
Import-Service: br.com.company.game.dao.api.IGameDAO;multiple:=false
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.7))"
Tool: Bnd-3.0.0.201509101326

分析:

我在 ap-dao 中进行了一些测试,然后才意识到如果我 return 实体没有通过 EntityManager,创建 objects 硬编码,例如,一切正常。一旦我使用 entityManager 查询实体,问题又回来了,我得到 ClassCastException。

private EntityManager entityManager;

    @SuppressWarnings("unchecked")
    @Override
    public List<Game> findAll() {
        return _findAllHardCoded(); // this work just fine in service layer, no ClassCastException

        return entityManager.createQuery("SELECT s FROM Game s").getResultList(); // if I use this, ClassCastException is generated in the service layer

    }

    protected List<Game> _findAllHardCoded() {
        List<Game> games = new ArrayList<Game>();
        games.add(new Game(Short.valueOf("1"), "Game1"));
        games.add(new Game(Short.valueOf("2"), "Game2"));
        return games;
    }

如果您的设置正确,那么 ap-data 应该包含 class 游戏,并且有一个 Export-Package 用于游戏所在的包。其他两个包应该有一个 Import-Package 语句用于这个包.在这种情况下,class 游戏只能由 ap-data 的 classloader 加载。

还要注意如何设置 maven bundle 插件。例如,如果您告诉它导出包含在另一个包中的包,那么它将把它嵌入到您自己的包中。所以可能最简单的方法是将其保留为默认值。

您可以查找的内容是。任何包裹都不应包含在超过一个包裹中。您应该使用 Aries JPA 进行 JPA 访问。正如 Balazs 评论的那样,持久性提供者经常在内部使用黑魔法。与 Aries JPA 结合使用时,它应该可以在 OSGi 中运行,但如果您使用纯 JPA,则可能会出现问题。

我查看了 github 上的项目。我认为问题是 persistence.xml 的位置。此文件应始终位于包含实体 classes 的项目中。你能试着移动它吗?

根据 Christian Schneider 的说法,如评论中所示,尝试在运行时更新 KAR 文件,它在任何持久性包中使用 EntityManager,在尝试转换实体类型的包之间生成 ClassCastException,这是 Aries JPA 的一个已知问题 1.x。 Aries JPA 2x 是最佳选择。谢谢!