question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Ambiguous services found

See original GitHub issue

Hello,

I’m trying to run the example here but I receive the following error and I have no idea what I’m doing wrong or it’s a bug in the framework itself?

Exception in thread "main" java.lang.IllegalArgumentException: Ambiguous services found for class com.zaxxer.hikari.HikariDataSource : [interface java.io.Closeable, interface javax.sql.DataSource]. Use register() methods to specify service.
	at io.activej.service.ServiceGraphModule.doLookupAdapter(ServiceGraphModule.java:600)
	at io.activej.service.ServiceGraphModule.lookupAdapter(ServiceGraphModule.java:570)
	at io.activej.service.ServiceGraphModule.getServiceOrNull(ServiceGraphModule.java:542)
	at io.activej.service.ServiceGraphModule.getCombinedServiceOrNull(ServiceGraphModule.java:474)
	at io.activej.service.ServiceGraphModule.doStart(ServiceGraphModule.java:428)
	at io.activej.service.ServiceGraphModule.doStart(ServiceGraphModule.java:401)
	at io.activej.service.ServiceGraphModule.lambda$serviceGraph$3(ServiceGraphModule.java:283)
	at io.activej.service.ServiceGraph.startFuture(ServiceGraph.java:278)
	at io.activej.service.ServiceGraphModule$1.start(ServiceGraphModule.java:296)
	at io.activej.launcher.Launcher.startServices(Launcher.java:235)
	at io.activej.launcher.Launcher.launch(Launcher.java:158)
	at ship.cars.dataone.WebApp.main(WebApp.java:73)

My snippet

import com.zaxxer.hikari.HikariDataSource;
import io.activej.config.Config;
import io.activej.http.AsyncServlet;
import io.activej.http.HttpResponse;
import io.activej.inject.annotation.Inject;
import io.activej.inject.annotation.Provides;
import io.activej.inject.module.AbstractModule;
import io.activej.inject.module.Module;
import io.activej.inject.module.Modules;
import io.activej.launcher.Launcher;
import io.activej.launchers.http.MultithreadedHttpServerLauncher;
import io.activej.promise.Promise;
import io.activej.service.ServiceGraphModule;
import ship.cars.dataone.utils.HikariConfigConverter;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;


public class WebApp extends MultithreadedHttpServerLauncher {
    @Inject
    DataSource dataSource;

    @Override
    protected void run() {
        try (Connection connection = dataSource.getConnection();
             Statement statement = connection.createStatement()
        ) {
            statement.executeUpdate("SELECT NOW();");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onStart() {
        System.out.println("TABLES BEFORE:");
    }

    @Override
    protected Module getOverrideModule() {
        return Modules.combine(
                ServiceGraphModule.create(),
                // db module
                new AbstractModule() {
                    @Provides
                    DataSource dataSource(Config config) {
                        HikariConfigConverter converter = HikariConfigConverter.create().withAllowMultiQueries();
                        return new HikariDataSource(config.get(converter, "hikari"));
                    }
                }
        );
    }

    @Provides
    AsyncServlet servlet() {
        return request -> Promise.of(
                HttpResponse.ok200()
                    .withPlainText("Hello, World!"));
    }

    public static void main(String[] args) throws Exception {
        Launcher launcher = new WebApp();
        launcher.launch(args);
    }
}

Thank you in advance 😃

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
eduard-vasinskyicommented, Jan 27, 2022

Hi, @vencivenc

Thank you for providing a snippet, this has greatly helped in pinpointing a problem.

Since MultithreadedHttpServerLauncher uses a ServiceGraphModule, all of the provided services are started/stopped by the ServiceGraph. A ServicGraphModule contains pre-registered ServiceAdapters that describe how a start/stop operation should be performed for a certain class.

A HikariDataSource implements both DataSource and Closeable interfaces. Service graph cannot choose whether it should start/stop a HikariDataSource as a DataSource or as a Closeable. You need to manually define a service adapter for HikariDataSource as a combination of Closeable and DataSource service adapters.

You can modify your snippet by replacing the ServiceGraphModule.create() line with:

ServiceGraphModule.create()
       .register(HikariDataSource.class, ServiceAdapters.combinedAdapter(
               ServiceAdapters.forCloseable(),
               ServiceAdapters.forDataSource()))

BTW, you should probably replace statement.executeUpdate("SELECT NOW();") with statement.executeQuery("SELECT NOW();")

1reaction
eduard-vasinskyicommented, Feb 1, 2022

ActiveJ Redis client works on top of ActiveJ AsyncTcpSocket, so it is ideal for our eventloop-based threading model. All the I/O is handled directly by the eventloop, so you do not need to use an external executor which would add the overhead of a thread context switching, etc.

As for using a connection pool, on second thought, I believe that your implementation of a single connection reuse is optimal for our threading model. A Redis server is single-threaded, so having multiple connections would not increase performance. All you need is a single connection per thread (worker). Your initial implementation from https://github.com/activej/activej/issues/149#issuecomment-1025743379 seems to be the correct one (although, you might need to add a reconnection handling routine).

I do not know why you got a performance drop when reusing a single connection. I did some testing/benchmarking and I got quite opposite results. The performance of a single connection is well above the performance of a new connection per request. On my machine, I benchmarked ~2 million requests per second using a single thread / single connection.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Ambiguous match found - Parser Error - MSDN - Microsoft
I'm getting the error below when running my ASP.Net 2.0 application. Any ideas why> I have looked for similar namespace names / class...
Read more >
How to Identify and Resolve Ambiguous CIs - TechDocs
Investigate any CI with a nonzero ambiguity index to determine if it is unique or it was inadvertently created. Ambiguous CIs can be...
Read more >
InversifyJS @multiInject not working, throws error "Ambiguous ...
You are getting "Ambiguous match found for serviceIdentifier" because when you get the container you are using the "weapon" identifier and ...
Read more >
AdminApp: "Ambiguous match found" error when viewing ...
An error with message "Ambiguous match found" is observed when viewing a dynamic content list in the backend. Steps to Reproduce.
Read more >
2 matches found based on name: network backdrop_default is ...
ERROR: for backdrop_mail_1 Cannot start service mail: network backdrop_default is ambiguous (2 matches found on name) Starting ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found