Problem EAR packaging

223 views
Skip to first unread message

Niklas Johansson

unread,
Feb 22, 2016, 10:33:14 AM2/22/16
to togglz-users
Hi

I'm trying to add Togglz to my application without any luck so far. My application is deployed as an ear. The ear contains an ejb jar and a war-file. I would like to have the war and ejb-jar code share the same toggle configuration. To accomplish this I've followed the instructions at http://www.togglz.org/documentation/advanced-config.html but without luck. When starting the application and pointing a browser to the console web application i get the following error:

16:05:42,279 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/caretrack].[TogglzConsoleServlet]] (http-/0.0.0.0:8080-3) JBWEB000236: Servlet.service() for servlet TogglzConsoleServlet threw exception: java.util.ServiceConfigurationError: org.togglz.core.spi.FeatureManagerProvider: Provider com.wirelesscar.vce.featuretoggling.EJBSingletonFeatureManagerProvider not a subtype
at java.util.ServiceLoader.fail(ServiceLoader.java:239) [jrebel-bootstrap-eea8bd346bc230e213a9a0575f4c9a73.jar:1.8.0_66]
at java.util.ServiceLoader.access$300(ServiceLoader.java:185) [jrebel-bootstrap-eea8bd346bc230e213a9a0575f4c9a73.jar:1.8.0_66]
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376) [jrebel-bootstrap-eea8bd346bc230e213a9a0575f4c9a73.jar:1.8.0_66]
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404) [jrebel-bootstrap-eea8bd346bc230e213a9a0575f4c9a73.jar:1.8.0_66]
at java.util.ServiceLoader$1.next(ServiceLoader.java:480) [jrebel-bootstrap-eea8bd346bc230e213a9a0575f4c9a73.jar:1.8.0_66]
at org.togglz.core.context.FeatureContext.getFeatureManagerOrNull(FeatureContext.java:83) [togglz-core-2.2.0.Final.jar:]
at org.togglz.core.context.FeatureContext.getFeatureManager(FeatureContext.java:43) [togglz-core-2.2.0.Final.jar:]
at org.togglz.core.manager.LazyResolvingFeatureManager.getDelegate(LazyResolvingFeatureManager.java:24) [togglz-core-2.2.0.Final.jar:]
at org.togglz.core.manager.LazyResolvingFeatureManager.getCurrentFeatureUser(LazyResolvingFeatureManager.java:49) [togglz-core-2.2.0.Final.jar:]
at org.togglz.console.TogglzConsoleServlet.isFeatureAdmin(TogglzConsoleServlet.java:68) [togglz-console-2.2.0.Final.jar:]
at org.togglz.console.TogglzConsoleServlet.service(TogglzConsoleServlet.java:55) [togglz-console-2.2.0.Final.jar:]
 
com.wirelesscar.vce.featuretoggling.EJBSingletonFeatureManagerProvider  is my FeatureManagerProvider implementation implementing the org.togglz.core.spi.FeatureManagerProvider interface. I'm running this in JBoss EAP 6.4, my war depends on togglz-console, the ejb-jar depends on togglz-core and togglz-cdi all with version 2.2.0.Final

I have a file named org.togglz.core.spi.FeatureManagerProvider in META-INF/services of my ejb-jar. It contains the full name of my FeatureManagerProvider: com.wirelesscar.vce.featuretoggling.EJBSingletonFeatureManagerProvider

I realize that I'm probably doing some stupid mistake but I just can't find it! :-)

All help appreciated
Thanks
Niklas

Christian Kaltepoth

unread,
Feb 22, 2016, 11:14:34 AM2/22/16
to togglz...@googlegroups.com
Hey,

no, I think there is no stupid mistake, but some weird classloader issue. ;)

I guess there are two versions of togglz-core on your classpath. One in the WAR's WEB-INF/lib directory and one in the root of your EAR. Try to exclude togglz-core in the WAR's pom:

    <dependency>
      <groupId>org.togglz</groupId>
      <artifactId>togglz-console</artifactId>
      <version>....</version>
      <exclusions>
        <exclusion>
          <groupId>org.togglz</groupId>
          <artifactId>togglz-core</artifactId>
        </exclusion>
      </exclusions> 
    </dependency>

I think this may help...

IIRC I did something similar in an EAR project. I could look up the config if the code shown above doesn't work for you.

Best regards

Christian

Niklas Johansson

unread,
Feb 23, 2016, 2:24:48 AM2/23/16
to togglz-users
That did it!

Thank you

//Niklas

Christian Kaltepoth

unread,
Feb 23, 2016, 4:13:01 AM2/23/16
to togglz...@googlegroups.com
Awesome! :)

Niklas Johansson

unread,
Feb 25, 2016, 10:42:28 AM2/25/16
to togglz-users
So now next problem :-)

Everything now works fine with in memory storage of state. Switching to JDBCStateRepository i run into problems. Starting with an empty database I would like Togglz to create it's table. I create a JDBCStateRepository instance giving it my datasource injected to my FeatureManagerSingleton. When Togglz tries to create it's table I get the following exception

java.sql.SQLSyntaxErrorException: ORA-02089: COMMIT is not allowed in a subordinate session

	oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
	oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
	oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951)
	oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513)
	oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227)
	oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
	oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:195)
	oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1036)
	oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1336)
	oracle.jdbc.driver.OracleStatement.executeUpdateInternal(OracleStatement.java:1845)
	oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:1810)
	oracle.jdbc.driver.OracleStatementWrapper.executeUpdate(OracleStatementWrapper.java:294)
	org.jboss.jca.adapters.jdbc.WrappedStatement.executeUpdate(WrappedStatement.java:375)
	org.togglz.core.repository.jdbc.SchemaUpdater.execute(SchemaUpdater.java:135)
	org.togglz.core.repository.jdbc.SchemaUpdater.migrateToVersion1(SchemaUpdater.java:39)
	org.togglz.core.repository.jdbc.JDBCStateRepository.migrateSchema(JDBCStateRepository.java:170)
	org.togglz.core.repository.jdbc.JDBCStateRepository.<init>(JDBCStateRepository.java:152)
	org.togglz.core.repository.jdbc.JDBCStateRepository.<init>(JDBCStateRepository.java:86)
	com.wirelesscar.vce.featuretoggling.FeatureManagerSingleton.getStateRepository(FeatureManagerSingleton.java:53)
	com.wirelesscar.vce.featuretoggling.FeatureManagerSingleton.init(FeatureManagerSingleton.java:28)

My DataSource is set up using XA-transactions could that be the cause for my problem? If so is it not possible to let Togglz set up the table?

Thanks

//Niklas

Christian Kaltepoth

unread,
Feb 25, 2016, 11:13:16 AM2/25/16
to togglz...@googlegroups.com
It may be possible that you have to disable autocommit mode in your setup. There is a configuration property in the JDBCStateRepository that allows to do this:


You can set it with a corresponding constructor.

Niklas Johansson

unread,
Feb 26, 2016, 2:50:38 AM2/26/16
to togglz-users
Trying that by using:
JDBCStateRepository stateRepository = JDBCStateRepository.newBuilder(dataSource)
            .noCommit(true)
            .build();
Unfortunately i get the same error. Reading up a bit on ORA-02089 and DDL statements it seems that a create table in Oracle commits the transaction. Commits are not allowed when using XA transactions so my conclusion is that you can not give Togglz a DataSource that uses xa if togglz is to set up the database. I've confirmed that it works when using a none xa DataSource. So either i have to create the table before starting Togglz or not use xa transactions.

I don't know if DDL statements making a commit is a special thing for Oracle, it might be worth a note on your advanced setup page.

Cheers
Niklas

Niklas Johansson

unread,
Feb 26, 2016, 4:21:27 AM2/26/16
to togglz-users
Setting the method that sets up the JDBCStateRepository as @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) also worked. I.e.:

    @PostConstruct
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public void init() throws Exception {

        JDBCStateRepository stateRepository = JDBCStateRepository.newBuilder(dataSource)
            .noCommit(true)
            .build();

        featureManager = new FeatureManagerBuilder()
            .featureEnum(Features.class)
            .stateRepository(new CachingStateRepository(stateRepository, 10000))  
            .userProvider(new NoOpUserProvider())
            .build();

Christian Kaltepoth

unread,
Feb 26, 2016, 9:31:45 AM2/26/16
to togglz...@googlegroups.com
AFAIK most database servers commit transactions for DDL statements.

You can also skip the creation of the database tables and create them manually. That's absolutely fine and a common practice when using Togglz in production. Especially as many production setups don't allow the connecting database user to user DDL statements.
Reply all
Reply to author
Forward
0 new messages