1

I come to you because I am stuck with my Jhipster Spring Boot application, when it comes to using Oracle and r2dbc.

Short description of my application

I have multiple maven profiles. One is called "dev" and it uses embeded H2 database. Everything works fine with it. I created a new maven Profile called 'local' in order to connect to my local Oracle Database. No problem at startutp and new tables located in liquibase changelog files are properly created with data in my Oracle database without any errors. Oracle version: Oracle Database 21c Express Edition Release 21.0.0.0.0 - Production

But If i call one of my apis that need to execute some queries then an error is raised with Oracle. Although it works fine when using h2 database. Do you know how I could resolve this problem ?

Below are listed the details of the error and some relevant parts of my configuration files.

Thanks a lot in advance

The JAVA code that provokes the error

In my controller class

@GetMapping("/authorities")
public Mono<List<String>> getAuthorities() {
    return userService.getAuthorities().collectList();
}

In my service class

@Transactional(readOnly = true)
public Flux<String> getAuthorities() {
    return authorityRepository.findAll().map(Authority::getName);
}

The stacktrace of the error

    java.lang.NoSuchMethodError: 'java.util.concurrent.Flow$Publisher oracle.jdbc.OracleConnectionBuilder.buildConnectionPublisherOracle()'
        at oracle.r2dbc.impl.OracleReactiveJdbcAdapter.lambda$publishConnection$8(OracleReactiveJdbcAdapter.java:643)
        at oracle.r2dbc.impl.OracleR2dbcExceptions.getOrHandleSQLException(OracleR2dbcExceptions.java:267)
        at oracle.r2dbc.impl.OracleReactiveJdbcAdapter.lambda$deferOnce$23(OracleReactiveJdbcAdapter.java:1060)
        at reactor.core.publisher.FluxSource.subscribe(FluxSource.java:67)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4400)
        at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onComplete(FluxConcatArray.java:258)
        at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:78)
        at reactor.core.publisher.Flux.subscribe(Flux.java:8469)
        at reactor.core.publisher.Flux.subscribeWith(Flux.java:8642)
        at reactor.core.publisher.Flux.subscribe(Flux.java:8439)
        at reactor.core.publisher.Flux.subscribe(Flux.java:8363)
        at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:423)
        at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:558)
        at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:268)
        at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:432)

Here are some configurations files that might be important:

The pom.xml file

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-r2dbc</artifactId> <!--  version 2.6.3   -->
</dependency>

...
  <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>             
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
            </dependency>
            <dependency>
                <groupId>io.r2dbc</groupId>
                <artifactId>r2dbc-h2</artifactId>
            </dependency>
        </dependencies>
    </profile>
<profile>
    <id>local</id>           
    <dependencies> 
    <!-- database oracles -->    
    <dependency>
        <groupId>com.oracle.database.r2dbc</groupId>
        <artifactId>oracle-r2dbc</artifactId> <!--  version 0.1.0  -->
    </dependency>           
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <configuration>
                    <filesets>
                        <fileset>
                            <directory>target/classes/static/</directory>
                        </fileset>
                    </filesets>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>build-info</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>io.github.git-commit-id</groupId>
                <artifactId>git-commit-id-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <properties>
        <!-- default Spring profiles -->
        <spring.profiles.active>local${profile.api-docs}${profile.tls}</spring.profiles.active>
    </properties>
</profile>    

The file application-local.yml

  liquibase:
    contexts: local, faker
    url: jdbc:oracle:thin:@localhost:1521/xe    
  mail:
    host: localhost
    port: 25
    username:
    password:
  r2dbc:
    url: r2dbc:oracle:thin://localhost:1521/xe
    username: MY_CREDIT    
    password: MY_CREDIT    

Other attempts I tried to change the r2dbc url to r2dbc:oracle:thin://localhost:1521:xe (: at the end) but it doesn't change anything. I also tried to add other dependencies in the pom like the one below, but no differences:

    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>21.1.0.0</version>
    </dependency>
    <dependency>
        <groupId>com.oracle.database.ha</groupId>
        <artifactId>ons</artifactId>
        <version>21.1.0.0</version>
    </dependency>
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ucp</artifactId>
        <version>21.1.0.0</version>
    </dependency>
Kris
  • 401
  • 2
  • 7
  • 16

1 Answers1

2

The error is occurring due to oracle-r2dbc runtime dependencies. To resolve this you would need to use ojdbc11 with JDK 11, instead of ojdbc8.

Source:

oracle-r2dbc

Oracle R2DBC relies on the Oracle JDBC Driver's Reactive Extensions APIs.

JDBC developer guide -

For using the JDBC Reactive Extensions, you must use the following:

  • JDBC Thin Driver 21c or later for building connections
  • JDK 11
  • ojdbc11.jar
nash
  • 193
  • 7
  • Great answer, @nash! I wrote about this issue in the Oracle R2DBC README: Other libraries may depend on a different version of Oracle JDBC which is incompatible. To resolve this incompatibility, it may be necessary to explicitly declare the dependency in your project, ie: com.oracle.database.jdbc ojdbc11 21.5.0.0 – Michael McMahon Sep 06 '22 at 20:07