"installing" an module in i got "Binding to Provider is not allowed"

544 views
Skip to first unread message

ich du

unread,
Jan 26, 2012, 4:34:26 AM1/26/12
to juk...@googlegroups.com
first thx for jukito - it's great!

i just tried the first time to "install" a module in configureTest:
    public static class Module extends JukitoModule {

        @Override
        protected final void configureTest() {
            install(new ServerModule());
        }
    }

(there is nothing more in the test, only a "test" that sysouts "here") But it doesn't work, i get: "Binding to Provider is not allowed".
What does this mean? And how to solve this?

thx in advance

scl

unread,
Jan 26, 2012, 4:41:40 AM1/26/12
to Jukito
"Binding to Provider is not allowed"

is an error message which comes from Guice.
Probably you are trying something similar to the following in your
ServerModule()

bind(new TypeLiteral<Provider<XXX>>(){}).to(CustomProvider.class);

instead you should do the following

bind(XXX.class).toProvider(CustomProvider.class)


You can post the content of your ServerModule(), if you need more help
in solving the problem

ich du

unread,
Jan 26, 2012, 4:51:18 AM1/26/12
to juk...@googlegroups.com
thx for quick reply,

First, the module is running fine. Only the Jukito test yields this error.

i do not bind any Provider the way you mentioned. The only thing i have is a "@Provides" Method that gets some Providers Injected:

    @Provides
    @Singleton
    @Inject
    public final SasDataProvider getSasDataProvider(final ServerConfig config,
                                                    final Provider<DataProviderFileImpl> sasFile,
                                                    final Provider<SasDataProviderHttpImpl> sasHttp) {
        if (config.getSasUrl().equalsIgnoreCase("DEMO")) {
            return sasFile.get();
        }
        return sasHttp.get();
    }

It chooses an implementation by config. Could that be the cause of the problem?

scl

unread,
Jan 26, 2012, 5:14:24 AM1/26/12
to Jukito
I tried to reproduce you error with the test below. So far I cannot
reproduce it.

can you try to nail down the problem by commenting out as many lines
in your ServerModule as possible until you have the minimal
configuration which produces the binding error.


------------------

import org.jukito.JukitoModule;
import org.junit.Test;

import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Provides;
import com.google.inject.Singleton;

public class BindingToProviderTest {

public static class MyModuel extends JukitoModule {

@Override
protected void configureTest() {
install(new ServerModule());
}
}

@Test
public void foo() {
System.out.println("done");
}

}

class ServerModule extends AbstractModule {

@Override
protected void configure() {

}

@Provides
@Singleton
@Inject
public final SasDataProvider getSasDataProvider(final ServerConfig
config,
final Provider<DataProviderFileImpl> sasFile, final
Provider<SasDataProviderHttpImpl> sasHttp) {
if (config.getSasUrl().equalsIgnoreCase("DEMO")) {
return sasFile.get();
}
return sasHttp.get();
}

}

interface SasDataProvider {
}

class ServerConfig {

public String getSasUrl() {
return "";
}
}

class DataProviderFileImpl implements SasDataProvider {
}

class SasDataProviderHttpImpl implements SasDataProvider {
}

ich du

unread,
Jan 26, 2012, 6:18:20 AM1/26/12
to juk...@googlegroups.com
thx for your effort,

the module can be installed as soon as i comment out the @Provides method mentioned above. It also works if i delete both providers injected as arguments. So the cause must be the injected Providers (i also tried to inject Provider<Object> - same error).
works:
 @Provides
    @Singleton
    @Inject
    public final SasDataProvider getSasDataProvider(final ServerConfig config) {
        return null;
    }

don't works:
 @Provides
    @Singleton
    @Inject
    public final SasDataProvider getSasDataProvider(final ServerConfig config,
                                                    final Provider<Object> sasHttp) {
        return null;
    }

Due to the fact that the module is working fine within the app, could that be an bug/problem in jukito?

In meantime i worked around the problem by binding all stuff needed by test manually line by line (i need only 3 bindings, so it's affordable ;-))

scl

unread,
Jan 26, 2012, 7:15:21 AM1/26/12
to Jukito
You are right, Jukito is the source of the error. I was able to
reproduce the behavior.
It has something to do with the way Jukito resolves the dependencies
which are needed to create all required bindings for a test.

The following code will trigger the error:

--------

import org.jukito.JukitoModule;
import org.jukito.JukitoRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.google.inject.Provider;
import com.google.inject.Provides;

@RunWith(JukitoRunner.class)
public class BindingToProviderTest {

public static class MyModuel extends JukitoModule {

@Override
protected void configureTest() {
}

@Provides
public final Object getObject(Provider<Object> op) {
return null;

ich du

unread,
Jan 26, 2012, 7:21:59 AM1/26/12
to juk...@googlegroups.com
thx again for your effort,

lets wait for a fix or a "more elegant" way to reuse/inherit modules.

Tim Peierls

unread,
Jan 26, 2012, 9:03:46 AM1/26/12
to juk...@googlegroups.com
On Thu, Jan 26, 2012 at 7:21 AM, ich du <tant...@hotmail.com> wrote:
thx again for your effort,

lets wait for a fix or a "more elegant" way to reuse/inherit modules.

The issue is orthogonal to the question of whether to provide a mechanism other than install for adding modules to the Jukito-created injector.

I put together an example to demonstrate that the issue is specifically Provider arguments to @Provides methods in Jukito:


--tim

Philippe Lhoste

unread,
Feb 25, 2013, 4:35:04 AM2/25/13
to juk...@googlegroups.com
On Thursday, 26 January 2012 12:18:20 UTC+1, ich du wrote:
Due to the fact that the module is working fine within the app, could that be an bug/problem in jukito?

In meantime i worked around the problem by binding all stuff needed by test manually line by line (i need only 3 bindings, so it's affordable ;-))

Bug: looks like it is, somebody created a bug after this discussion.
http://code.google.com/p/jukito/issues/detail?id=34
One year later, the bug is still listed as "new"...

Not being expert at injection, I would be glad if you could show explicitly the kind of code required to workaround the issue. Thank you.

Tim Peierls

unread,
Feb 25, 2013, 7:58:31 AM2/25/13
to juk...@googlegroups.com
The general case is a @Provides method in an AbstractModule that will be installed by a Jukito test:

    @Provides
    Foo getFooInstance(Provider<Bar> barProvider, ... other args, maybe ...) {
        ... call barProvider.get(), possibly more than once, in order to provide a Foo ...
    }

The main reason to use a Provider in the first place is to allow multiple calls to get(). If you don't need to do that, it's probably best to inject the type directly:

    @Provides
    Foo getFooInstance(Bar bar, ... other args, maybe ...) {
        ... use bar to provide a Foo ...
    }

If you really need a Provider here, the workaround is to declare a concrete class that behaves like a Provider (you can do it as part of the same AbstractModule that has the @Provides method:

    static class BarProvider {
        final Provider<Bar> bp;
        @Inject BarProvider(Provider<Bar> bp) { this.bp = bp; }
        public Bar get() { return bp.get(); }
    }

and use BarProvider instead of Provider<Bar>:

    @Provides
    Foo getFooInstance(BarProvider barProvider, ... other args, maybe ...) {
        ... call barProvider.get(), possibly more than once, in order to provide a Foo ...
    }

--tim

Philippe Lhoste

unread,
Feb 26, 2013, 11:55:33 AM2/26/13
to juk...@googlegroups.com, t...@peierls.net
Thanks for the information, but my use case is slightly different, I think.

The odd thing is that shortly after sending the above message, I did a mvn clean package and the problem auto-magically disappeared!
But today, it is back with revenge... I can't understand the logic of the issue.

What we do: we have defined lot of GWTEvent<type> classes (we don't use GWTP, alas, on this project...) and to avoid doing eventBus.fire(new SomeEvent()) (we want to inject as much as possible), we use providers to generate them:
Provider<SomeEvent> factory;
evenBus.fire(factory.get());
The Event classes have no constructors (relying on the default constructor, with setter to put the parameters).

We don't define explicitly the provider, we inject it in the constructor of the class using it and let Gin to do the new instantiation for us.

My question is: do we need to be more explicit for Jukito? To define something in the configure() call?

Tim Peierls

unread,
Feb 26, 2013, 12:36:00 PM2/26/13
to juk...@googlegroups.com
The immediate problem is that @Provides Foo foo(Provider<Bar> barP) { ... } doesn't work in Jukito, right? 

If so, I don't understand why the workaround I described won't work for you: Replace Provider<Bar> with BarProvider in those @Provides methods and define BarProvider to be injected with Provider<Bar>.

If not ... then I don't understand the problem.

--tim


--
You received this message because you are subscribed to the Google Groups "Jukito" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jukito+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Philippe Lhoste

unread,
Feb 27, 2013, 3:25:29 AM2/27/13
to juk...@googlegroups.com, t...@peierls.net
On Tuesday, 26 February 2013 18:36:00 UTC+1, Tim Peierls wrote:
The immediate problem is that @Provides Foo foo(Provider<Bar> barP) { ... } doesn't work in Jukito, right? 

If so, I don't understand why the workaround I described won't work for you: Replace Provider<Bar> with BarProvider in those @Provides methods and define BarProvider to be injected with Provider<Bar>.

If not ... then I don't understand the problem.

Sorry for not being clear, it is hard to explain without pasting tons of code...
We don't have @Provides annotations (for these events, at least), we just rely on Gin / Guice to instantiate the classes from the default constructor.
Maybe we need to be more explicit, but then, it would be easier / simpler to use 'new' where needed, after all these are lightweight classes created on the fly and with short lifespan.

Philippe Lhoste

unread,
Feb 27, 2013, 3:44:17 AM2/27/13
to juk...@googlegroups.com, t...@peierls.net
We remove some of these providers, but kept the older ones, that were working in the previous commit.
Basically, these events, handlers and providers are just copy / paste of each other, with just some little changes (name, of course, and kind of transported data).
So it is even more puzzling why it works for some cases and not for the others.

BTW, thanks for the help.

Philippe Lhoste

unread,
Feb 27, 2013, 5:11:44 AM2/27/13
to juk...@googlegroups.com, t...@peierls.net
On Wednesday, 27 February 2013 09:44:17 UTC+1, Philippe Lhoste wrote:
We remove some of these providers, but kept the older ones, that were working in the previous commit.

Cryptic... I meant that we fixed the tests by removing some of the new providers. We don't see why some are OK while others fail, since these are almost identical.

Tim Peierls

unread,
Feb 27, 2013, 7:32:06 AM2/27/13
to juk...@googlegroups.com
All my responses were predicated on the idea that you were talking about a specific bug involving @Provides methods with Provider<X> arguments. 

So I don't think I can help you.

--tim

--

Maxime Mériouma-Caron

unread,
Nov 15, 2013, 10:24:17 PM11/15/13
to juk...@googlegroups.com
I know this is an old thread, but we released Jukito version 1.3 today, which allows binding to providers.
Reply all
Reply to author
Forward
0 new messages