Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cassandra unit on Java 9 #249

Open
mp911de opened this issue Sep 29, 2017 · 20 comments
Open

Cassandra unit on Java 9 #249

mp911de opened this issue Sep 29, 2017 · 20 comments

Comments

@mp911de
Copy link

mp911de commented Sep 29, 2017

This is more of a to-be-done ticket as soon as Cassandra supports Java 9.

Right now, Cassandra fails on Java 9 because of initialization errors that are attempted to be reported but reporting fails because of uninitialized DatabaseDescriptor.
Setting up the configuration

        System.setProperty("cassandra.config", "file:" + file.getAbsolutePath());
        System.setProperty("cassandra-foreground", "true");
        System.setProperty("cassandra.native.epoll.enabled", "false"); // JNA doesnt cope with relocated netty

Before calling org.cassandraunit.utils.EmbeddedCassandraServerHelper#rmdir initializes DatabaseDescriptor eagerly yet Cassandra still fails because of the illegal access to ByteBuffer.cleaner().

Related ticket: https://issues.apache.org/jira/browse/CASSANDRA-9608

@nachii
Copy link

nachii commented Jan 12, 2018

Hi,
I “resolved” the initialization of the DatabaseDescriptor adding these 2 lines:

System.setProperty("cassandra.config", "file:///" + “/path/to/yaml/file/file_name.yaml");
DatabaseDescriptor.daemonInitialization();

before

EmbeddedCassandraServerHelper.startEmbeddedCassandra(“file_name.yaml");

but now I have this error:

[pool-2-thread-1] ERROR o.a.c.service.CassandraDaemon - Exception encountered during startup
java.lang.IncompatibleClassChangeError: Inconsistent constant pool data in classfile for class org/apache/cassandra/utils/btree/UpdateFunction. Method lambda$static$0(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; at index 45 is CONSTANT_MethodRef and should be CONSTANT_InterfaceMethodRef
	at org.apache.cassandra.utils.btree.UpdateFunction.<clinit>(UpdateFunction.java:66) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.utils.btree.BTree$Builder.build(BTree.java:1108) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.utils.btree.BTreeSet$Builder.build(BTreeSet.java:608) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.db.PartitionColumns$Builder.build(PartitionColumns.java:196) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.config.CFMetaData$Builder.build(CFMetaData.java:1327) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.config.CFMetaData.compile(CFMetaData.java:427) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.schema.SchemaKeyspace.compile(SchemaKeyspace.java:266) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.schema.SchemaKeyspace.<clinit>(SchemaKeyspace.java:114) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.config.Schema.<init>(Schema.java:69) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.config.Schema.<clinit>(Schema.java:49) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.service.StartupChecks$10.execute(StartupChecks.java:371) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.service.StartupChecks.verify(StartupChecks.java:116) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:200) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:600) ~[cassandra-unit-shaded-3.3.0.2.jar:na]
	at org.cassandraunit.utils.EmbeddedCassandraServerHelper.lambda$startEmbeddedCassandra$1(EmbeddedCassandraServerHelper.java:144) [cassandra-unit-shaded-3.3.0.2.jar:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) ~[na:na]
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) ~[na:na]
	at java.base/java.lang.Thread.run(Thread.java:844) ~[na:na]

Maybe it could be useful to someone.

I saw that there is a patch in the related ticket https://issues.apache.org/jira/browse/CASSANDRA-9608. When will CassandraUnit be patched to support Java 9?

By the way, for now, I've found a workaround.
I start the embedded DB as an external process launching a jar with JDK 8 and then I run the unit tests from my application with JDK 9.
For a CI environment I use the Exec Maven Plugin to run the external jar before the tests.
The only requirement is to have both JDK installed.
What do you think about it?

Thanks

@lukasz-gosiewski
Copy link

lukasz-gosiewski commented Mar 20, 2018

I will add some details to this issue instead of starting a new one. For today, cassandra-unit still crashes on startup on Java 9. I created a sample demo project to reproduce the issue. Both Mave and Gradle are affected. Here's the stacktrace:

java.lang.ExceptionInInitializerError
	at org.cassandraunit.utils.EmbeddedCassandraServerHelper.mkdir(EmbeddedCassandraServerHelper.java:302)
	at org.cassandraunit.utils.EmbeddedCassandraServerHelper.copy(EmbeddedCassandraServerHelper.java:289)
	at org.cassandraunit.utils.EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.java:99)
	at org.cassandraunit.utils.EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.java:81)
	at org.cassandraunit.utils.EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.java:73)
	at org.cassandraunit.utils.EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.java:69)
	at com.gosiewski.demo.CassandraIntegrationTest.init(CassandraIntegrationTest.java:16)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NullPointerException
	at org.apache.cassandra.config.DatabaseDescriptor.getDiskFailurePolicy(DatabaseDescriptor.java:1881)
	at org.apache.cassandra.utils.JVMStabilityInspector.inspectThrowable(JVMStabilityInspector.java:82)
	at org.apache.cassandra.io.util.FileUtils.<clinit>(FileUtils.java:79)
	... more

And here's the link to repo:
https://github.com/lukasz-gosiewski/cassandra-unit-crash-sample

@lukasz-gosiewski
Copy link

lukasz-gosiewski commented Mar 20, 2018

@nachii
Could you please explain this a bit more?

By the way, for now, I've found a workaround.
I start the embedded DB as an external process launching a jar with JDK 8 and then I run > the unit tests from my application with JDK 9.
For a CI environment I use the Exec Maven Plugin to run the external jar before the tests.
The only requirement is to have both JDK installed.
What do you think about it?

Is this working?

@mp911de
Copy link
Author

mp911de commented Mar 20, 2018

Looking at CASSANDRA-9608:

This patch won't make into any current release - i.e. none of 2.1, 2.2, 3.0, 3.11. The changes are too intrusive.

Given that Java 9 will be EOL's, when Java 10 is released and 10 will EOL when 11 is released (6 months in between), the earliest newer version that will be supported is the one that's current when 4.0 goes GA.

This ticket seems to remain open for quite a while.

@jsevellec
Copy link
Owner

Yes, the main problem is that cassandra-unit is starting in the same JVM an instance of Cassandra which does not work on Java 9 at the moment...

@lukasz-gosiewski
Copy link

@jsevellec
Yup, i understand that. But I'm wondering if there is any fix that will allow us to stay on Java 9. Cassandra as you see won't release support for Java 9 in nearest future, so we need to decide if we can avoid migrating back to Java 8.

@nachii
Copy link

nachii commented Mar 21, 2018

@lukasz-gosiewski yes, it's working. I'll try to explain it better.
I created a tiny Spring Boot app with JDK 1.8 that simply start the embedded Cassandra:

@SpringBootApplication
public class Application {
    public static void main(String[] args) throws IOException, TTransportException {
        EmbeddedCassandraServerHelper.startEmbeddedCassandra("embedded-cassandra.yaml");
    }
}

Then I have a Spring Boot app built with JDK 9 where there are the tests that use CassandraUnit.
During the development, I start the tiny app manually and then I launch the tests.
For the build phase, I used this Maven plugin:

...
<properties>
<!-- Default value to allow Jenkins build run. -->
    <jdk8.path>java</jdk8.path>
</properties>
...
<!--
  Plugin that starts the embedded Cassandra before the unit tests are run.
  In the Jenkins CI environment this will be ignored because of a connection error. Pre-step build have been added instead.
-->
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>1.6.0</version>
  <executions>
    <execution>
      <phase>generate-test-sources</phase>
      <goals>
        <goal>exec</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <executable>${jdk8.path}</executable>
    <arguments>
      <argument>-classpath</argument>

      <!-- automatically creates the classpath using all project dependencies,
           also adding the project build directory -->
      <classpath/>

      <argument>com.example.embedded.cassandra.Application</argument>
    </arguments>
    <async>true</async>

    <!-- Ignore errors when exit code is 1. -->
    <successCodes>0,1</successCodes>

  </configuration>
</plugin>

And I launch Maven like this:

mvn clean install -Djdk8.path=/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/bin/java

In this way, the embedded Cassandra is launched in a separate process before the tests execution that will be killed automatically at the end of the build.
In Jenkins, I added a pre-step build where you can launch the tiny app.

It seems that with TestContainers (https://www.testcontainers.org/) we can start a Docker container directly from JUnit, but I haven't tried it yet.

I hope I was clear.

@raphaelLacerda
Copy link

raphaelLacerda commented Jul 26, 2018

still not working with Java10

`

@Rule
    public CassandraCQLUnit cassandraCQLUnit = new CassandraCQLUnit(new               ClassPathCQLDataSet("simple.cql","keyspaceNameToCreate"));

@Test
public void should_have_started_and_execute_cql_script() throws Exception {
    ResultSet result = cassandraCQLUnit.session.execute("select * from mytable WHERE id='myKey01'");
    assertThat(result.iterator().next().getString("value"), is("myValue01"));

`

this code just works with Java 8

@eximius313
Copy link

@fabianpiau
Copy link

fabianpiau commented Oct 16, 2018

The workaround proposed by @nachii is fine with Java 10, but it is not working with Java 11 (see stacktrace below)

Cassandra is now compatible Java 11.
Are they any plans to make Cassandra unit compatible with Java 11?

java.lang.ExceptionInInitializerError
	at org.github.jamm.MemoryMeter.measure(MemoryMeter.java:178)
	at org.apache.cassandra.utils.ObjectSizes.measure(ObjectSizes.java:163)
	at org.apache.cassandra.utils.ObjectSizes.<clinit>(ObjectSizes.java:39)
	at org.apache.cassandra.dht.Murmur3Partitioner.<clinit>(Murmur3Partitioner.java:46)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:315)
	at org.apache.cassandra.utils.FBUtilities.classForName(FBUtilities.java:464)
	at org.apache.cassandra.utils.FBUtilities.instanceOrConstruct(FBUtilities.java:480)
	at org.apache.cassandra.utils.FBUtilities.newPartitioner(FBUtilities.java:430)
	at org.apache.cassandra.utils.FBUtilities.newPartitioner(FBUtilities.java:416)
	at org.apache.cassandra.config.DatabaseDescriptor.applyPartitioner(DatabaseDescriptor.java:992)
	at org.apache.cassandra.config.DatabaseDescriptor.applyAll(DatabaseDescriptor.java:312)
	at org.apache.cassandra.config.DatabaseDescriptor.daemonInitialization(DatabaseDescriptor.java:142)
	at com.hotels.usernotification.functional.support.OrderedCassandraTestExecutionListener.beforeTestClass(OrderedCassandraTestExecutionListener.java:26)
	at org.springframework.test.context.TestContextManager.beforeTestClass(TestContextManager.java:215)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:60)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 5
	at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
	at java.base/java.lang.String.substring(String.java:1874)
	at org.github.jamm.MemoryLayoutSpecification.getEffectiveMemoryLayoutSpecification(MemoryLayoutSpecification.java:190)
	at org.github.jamm.MemoryLayoutSpecification.<clinit>(MemoryLayoutSpecification.java:31)
	... 24 more

@mp911de
Copy link
Author

mp911de commented Oct 16, 2018

@fabianpiau have you tried upgrading to jamm 0.3.2?

@fabianpiau
Copy link

No, I see I have a dependency on 0.3.0
Let me try now...

@fabianpiau
Copy link

Yes it's working, thanks a lot for the tip!
Still will be nice to have a new Cassandra unit version working with Java 11 out of the box without any hack :)

@jsevellec
Copy link
Owner

At the end it's just a of dependency management and which dependency version does cassandra-unit bring with him by default

Would you mind to share to propose a PR for CU containing the good dependency versions?

@mp911de
Copy link
Author

mp911de commented Oct 16, 2018

I'd personally wait until Cassandra 4 is available to get full Java 11 support.

@fabianpiau
Copy link

I have created #282.
Following @mp911de comment, feel free to merge or decline it, if you prefer waiting for a new Cassandra version.

@jsevellec
Copy link
Owner

thanks for your time!

@umangsingh123
Copy link

umangsingh123 commented Jan 11, 2019

Hi ,
i am in the process of Migrating our App to JDK 11 and we are using this API as our Unit testing framework for Cassandra .
It gives me the below exception which i think aligns as per the thread.
Could you let me know when are you planning to have a fix for this .

java.lang.ExceptionInInitializerError at org.cassandraunit.utils.EmbeddedCassandraServerHelper.rmdir(EmbeddedCassandraServerHelper.java:294) at org.cassandraunit.utils.EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.java:105) at org.cassandraunit.utils.EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.java:88) at org.cassandraunit.utils.EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.java:80) at com.bestbuy.esp.dao.TestActivationPackageDAO.startCassandraEmbedded(TestActivationPackageDAO.java:98) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) Caused by: java.lang.NullPointerException at org.apache.cassandra.config.DatabaseDescriptor.getDiskFailurePolicy(DatabaseDescriptor.java:1881) at org.apache.cassandra.utils.JVMStabilityInspector.inspectThrowable(JVMStabilityInspector.java:82) at org.apache.cassandra.io.util.FileUtils.<clinit>(FileUtils.java:79) ... 22 more

Version Details -->
Java 11 .
Gradle 5
Using Spring data cassandra latest Version.
Datastax Core and mapper APIs latest Version

@umangsingh123
Copy link

Any Update on this Thread .

@RuslanPopenko
Copy link

Hello guys!

Have you resolved this issue?

GDownes added a commit to newrelic/newrelic-java-agent that referenced this issue Feb 1, 2022
twcrone pushed a commit to newrelic/newrelic-java-agent that referenced this issue Feb 2, 2022
* Support for Cassandra dataStax driver 4

#202

* Exclude instrumentation for pre 4.0.0 release versions

#202

* Exclude unit tests for Java 9+

Cassandra Unit issue -
jsevellec/cassandra-unit#249
#202
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants