google / google/guice

Bug: Binding to `Scopes.NO_SCOPE` does not "overrule" `@Singleton`

Open
#1,869 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
12.7k
Forks
1.7k
Avg merge
11m
Merged PRs (30d)
2

Description

In your [Scopes](https://github.com/google/guice/wiki/Scopes#applying-scopes) docs you state:
> If there's conflicting scopes on a type and in a `bind()` statement, the `bind()` statement's scope will be used. **If a type is annotated with a scope that you don't want, bind it to `Scopes.NO_SCOPE`**.

But that does not work in practice using latest Guice 7. I tried every version down to 2.0 and it never worked.
Or maybe I understand or implemented something wrong?

I created a reproducer you can [find here](https://github.com/mkurz/guice-noscope/) that you can run with
```
mvn clean package exec:java -Dexec.mainClass=com.example.Main
```

Pasting the code here too:

```java
public interface Hello {}
```

The instance of `Hello` is annotated as singleton:

```java
import com.google.inject.Singleton;
//import jakarta.inject.Singleton; // Makes no difference

@Singleton
public class EnglishHello implements Hello {}
```

In the module however I apply `NO_SCOPE` to the binding:

```java
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;

public class HelloModule extends AbstractModule {
@Override
protected void configure() {
bind(Hello.class).to(EnglishHello.class)
.in(Scopes.NO_SCOPE); // This should "override" the @Singleton annotation IMHO
}
}
```

However, the same instance of the `Hello` implemention will be printed to the output:

```java
Injector injector = Guice.createInjector(new HelloModule());

// Does not work, output shows same instance
System.out.println(injector.getInstance(Hello.class));
System.out.println(injector.getInstance(Hello.class));
```

Further:
- If I remove the `@Singleton` annotation of course things behave correctly and new instances will be created each time.
- Even more, again without the `@Singleton` annotation, but with binding to `.in(Scopes.SINGLETON);` (instead of `.in(Scopes.NO_SCOPE);`) that also behaves as expected and the same instance will be reused.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.