TomEE, Hazelcast и jca-rar

Я пытаюсь добавить поддержку транзакций в свой кеш Hazelcast. Для этого я обнаружил, что у Hazelcast есть jca-rar, который дает мне фабрику соединений, которую я могу использовать. Вот что я сделал до сих пор:

  1. Я поместил этот файл .rar в свою папку WEB-INF/lib.
  2. Я установил tomee.unpack.dir = work/ в файле system.properties.
  3. Мой pom.xml файл:

    <project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
        <modelVersion>4.0.0</modelVersion>
        <groupId>test</groupId>
        <artifactId>cachetest</artifactId>
        <version>0.0.1</version>
        <packaging>war</packaging>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <hazelcast.version>3.6.2</hazelcast.version>
        </properties>
        <build>
            <finalName>${project.artifactId}</finalName>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.5</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                        <archive>
                            <manifestEntries>
                                <Dependencies>com.hazelcast</Dependencies>
                            </manifestEntries>
                        </archive>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        <dependencies> 
            <dependency>
                <groupId>com.fasterxml.jackson.jaxrs</groupId>
                <artifactId>jackson-jaxrs-json-provider</artifactId>
                <version>2.4.3</version>
            </dependency>
            <dependency>
                <groupId>com.hazelcast</groupId>
                <artifactId>hazelcast</artifactId>
                <version>${hazelcast.version}</version>
            </dependency>
            <dependency>
                <groupId>com.hazelcast</groupId>
                <artifactId>hazelcast-jca</artifactId>
                <version>${hazelcast.version}</version>
            </dependency>
            <dependency>
                <groupId>com.hazelcast</groupId>
                <artifactId>hazelcast-jca-rar</artifactId>
                <version>${hazelcast.version}</version>
                <type>rar</type>
            </dependency>
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-web-api</artifactId>
                <version>6.0</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </project>
    
  4. Я добавляю службу отдыха для целей тестирования.

    @Path("resttest")
    @Stateless
    public class RestService {
    
        @Resource(mappedName = "hazelcast-jca-rar-3.6.2RA")
        private ConnectionFactory connectionFactory;
    
        @GET
        @Path("create")
        public void createGame() throws ResourceException {
            connectionFactory.getConnection();//ClassCastException
        }
    }
    

Мой web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

    <display-name>Cachetest</display-name>

    <session-config>
        <session-timeout>90</session-timeout>
    </session-config>

</web-app>

Мой томи.xml:

<?xml version="1.0" encoding="UTF-8"?>
<tomee>

    <Deployments dir="apps" />
</tomee>

Это действительно весь код, который у меня есть в моем простом тесте, и он терпит неудачу при попытке получить соединение из фабрики соединений с помощью ClassCassException:

INFO: HZ Connection Event <<FACTORY_INIT>> for hazelcast.ManagedConnectionFactoryImpl [1] in thread [http-bio-8080-exec-7]
java.lang.Exception: Hz Connection Event Call Stack
    at com.hazelcast.jca.ManagedConnectionFactoryImpl.logHzConnectionEvent(ManagedConnectionFactoryImpl.java:167)
    at com.hazelcast.jca.ManagedConnectionFactoryImpl.createConnectionFactory(ManagedConnectionFactoryImpl.java:91)
    at com.hazelcast.jca.ManagedConnectionFactoryImpl.createConnectionFactory(ManagedConnectionFactoryImpl.java:44)
    at org.apache.openejb.core.ConnectorReference.getObject(ConnectorReference.java:50)
    at org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:175)
...
SEVERE: EjbTransactionUtil.handleSystemException: com.sun.proxy.$Proxy114 cannot be cast to com.hazelcast.jca.HazelcastConnectionImpl
java.lang.ClassCastException: com.sun.proxy.$Proxy114 cannot be cast to com.hazelcast.jca.HazelcastConnectionImpl
    at com.hazelcast.jca.ConnectionFactoryImpl.getConnection(ConnectionFactoryImpl.java:89)
    at com.hazelcast.jca.ConnectionFactoryImpl.getConnection(ConnectionFactoryImpl.java:79)
    at com.hazelcast.jca.ConnectionFactoryImpl.getConnection(ConnectionFactoryImpl.java:36)

кто-нибудь знает, почему это произошло? Я пропустил какую-то конфигурацию?

Моя версия TomEE 1.7.4 и версия hazelcast 3.6.2 (как написано в pom).


person Runar Halse    schedule 20.04.2016    source источник
comment
Можете ли вы поделиться tomee.xml и web.xml тоже?   -  person ibrahim gürses    schedule 21.04.2016
comment
добавил код, там ничего особенного, но может я что-то упустил?   -  person Runar Halse    schedule 22.04.2016


Ответы (2)


Это плохо. Короче: у тебя проблемы.

Описание ошибки довольно ясное: JDK Dynamic Proxy не может быть приведен к классу. Это ожидаемое поведение, поскольку прокси-серверы JDK могут реализовывать только интерфейсы. Это специфичная для TomEE проблема, поскольку большинство крупных поставщиков серверов приложений используют собственные технологии проксирования с поддержкой классов (JBoss Javassist, Spring CGLIB и т. д.), в то время как TomEE застрял на проксировании JDK. TomEE вроде бы признает проблему, но заявляет, что «вряд ли она будет решена в ближайшее время». Дополнительную информацию см. здесь.

Причина, по которой Hazelcast терпит неудачу, заключается в том, что они передают объект подключения своей реализации, а не интерфейсу (см. источник). Ничего криминального в таком поведении внутреннего кода нет, но иногда это не пригодится.

Теперь к практической части. Я не вижу возможности исправить это «настройкой». Если вы готовы пропатчить Hazelcast RA, то вы можете либо заменить приведение классов на интерфейсное, либо использовать DissociatableManagedConnection, упоминалось, что это удобно в таких ситуациях.

public class HazelcastManagedConnectionImpl extends JcaBase 
            implements ManagedConnection, LocalTransaction, 
            LocalTransaction, DissociatableManagedConnection {

      @Override
      public void dissociateConnections() throws ResourceException {
            conn = null;
      }
...
}

Но, на самом деле, я бы посоветовал вам пересмотреть свой выбор сервера приложений. Доля рынка TomEE невелика не без причины: почти для всего используются собственные контейнеры, что затрудняет разработчикам поддержание их в актуальном состоянии. Wildfly может быть хорошим вариантом (по крайней мере, 9-я версия достаточно стабильна, и мои адаптеры ресурсов в ней работают хорошо).

person Roman Nazarenko    schedule 25.04.2016
comment
Спасибо за хороший ответ. К сожалению, я не могу заменить TomEE. У вас есть дополнительная информация о подходе DissociatableManagedConnection? - person Runar Halse; 26.04.2016
comment
Я обновил ответ примером. DissociatableManagedConnection по-прежнему требует взлома RAR, поэтому мне лучше остановиться на удалении приведения классов. - person Roman Nazarenko; 26.04.2016
comment
Спасибо за помощь. Я скачал исходный код Hazelcast-Ra, исправил приведение, и теперь он работает без ClassCastException. Однако кеш по-прежнему не будет откатываться при откате контейнера. - person Runar Halse; 26.04.2016
comment
Привет, Рунар, мы увидели твое исправление, и оно уже объединено с мастером. Не могли бы вы написать мне на chris_at_hazelcast_com? :) - person noctarius; 26.04.2016