Guice: Mensaje de error engañoso con inyector infantil

Creado en 7 nov. 2014  ·  11Comentarios  ·  Fuente: google/guice

Si tiene un inyector secundario y le solicita al inyector principal un valor para un enlace definido en el secundario, obtendrá el error "Ya estaba configurado en uno o más inyectores secundarios".

Sería mejor decir "No se vinculó ninguna implementación para ..., aunque está configurado en un inyector secundario".

Aquí hay un código de muestra:

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;

public class GuiceBug {

    public static void main(String[] args) {
        Injector i1 = Guice.createInjector();
        Injector i2 = i1.createChildInjector(
                new AbstractModule() {
                        <strong i="8">@Override</strong>
                        protected void configure() {
                            bind(IStuff.class).to(Stuff.class);
                        }
                    });
        i1.getInstance(IStuff.class);
    }

    static interface IStuff {}

    static class Stuff implements IStuff {}
}
Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:

1) Unable to create binding for org.enercoop.test.GuiceBug$IStuff. It was already configured on one or more child injectors or private modules
    bound at org.enercoop.test.GuiceBug$1.configure(GuiceBug.java:15)
  If it was in a PrivateModule, did you forget to expose the binding?
  while locating org.enercoop.test.GuiceBug$IStuff

1 error
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1004)
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:961)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1013)
    at GuiceBug.main(GuiceBug.java:18)

Comentario más útil

No puedo evitar pensar que @laurentmartelli tenía razón sobre este error.

  • Con mi llamada bind , recibo este error
  • Si comento mi llamada bind , obtengo " No implementation for ... was bound "

¿Cómo puedo tener demasiados enlaces, luego eliminar un enlace y luego no tener suficientes?

Todos 11 comentarios

¿Qué te hace decir que es engañoso? El error es correcto: no puede obtener el enlace del padre porque está enlazado en el hijo. Comenzar con "no se ató la implementación" parece más engañoso, porque uno _estaba_ atado... simplemente en un lugar diferente.

Decir " ya estaba configurado" me hace pensar que se configuró dos veces, lo cual no es el caso. No sugiere que se configuró en otro lugar. Si configura un enlace tanto en el padre como en el hijo, también obtendrá "Un enlace a... ya estaba configurado en...".

Si tienes una manzana y alguien toma esa manzana, cuando intentas obtenerla el resultado es "No puedes, alguien ya tomó la manzana". La manzana no fue tomada dos veces. Cuando intenta obtenerlo (la primera vez para usted, la segunda vez en total), le dicen que ya fue tomado.

Esto es lo mismo. Intenta crear un enlace en el padre (obteniendo un enlace que aún no existe) y el resultado es que se le dice que no puede crear el enlace porque ya estaba configurado en un inyector secundario.

Entiendo su punto, pero todavía encuentro esto confuso, porque " Los elementos del inyector secundario no son visibles para su padre ". Entonces, si quiero algo del padre que no está definido en él, falla solo por eso, no por nada definido o no en los hijos.

Eso es incorrecto. Falla precisamente porque está definido en el niño. Si simplemente no se definió en el padre, entonces el enlace se crearía en tiempo de ejecución como un enlace justo a tiempo. Sin embargo, no puede crear el enlace justo a tiempo porque el enlace ya existe en el elemento secundario y Guice no permite enlaces tanto en el elemento principal como en el elemento secundario.

No puedo evitar pensar que @laurentmartelli tenía razón sobre este error.

  • Con mi llamada bind , recibo este error
  • Si comento mi llamada bind , obtengo " No implementation for ... was bound "

¿Cómo puedo tener demasiados enlaces, luego eliminar un enlace y luego no tener suficientes?

Para tu información, también encontré esto extremadamente confuso.

NOTA: los inyectores para niños son extremadamente confusos. Nos esforzamos por evitar usarlos internamente.

Sí, el mensaje de error es confuso. Sin embargo, ahora buscar en Google el error dará esta discusión y permitirá que las personas lo resuelvan a pesar de la redacción. Gracias @laurentmartelli!

+ 1 en esto

También fue confuso para mí, buscar en Google esta discusión resultó ser la forma más rápida de encontrar la causa real, por lo que el mensaje también podría tener un enlace a esta discusión.

¿Fue útil esta página
0 / 5 - 0 calificaciones