Skip to content

Commit 7ae663f

Browse files
authored
Revert "[MNG-7347] SessionScoped beans should be singletons for a given session (#653)" (#715)
This reverts commit b4518b5.
1 parent 5e2e0d8 commit 7ae663f

5 files changed

Lines changed: 95 additions & 226 deletions

File tree

maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,8 @@ public void buildProject( MavenSession session, MavenSession rootSession, Reacto
9090

9191
// session may be different from rootSession seeded in DefaultMaven
9292
// explicitly seed the right session here to make sure it is used by Guice
93-
final boolean scoped = session != rootSession;
94-
if ( scoped )
95-
{
96-
sessionScope.enter();
97-
sessionScope.seed( MavenSession.class, session );
98-
}
93+
sessionScope.enter( reactorContext.getSessionScopeMemento() );
94+
sessionScope.seed( MavenSession.class, session );
9995
try
10096
{
10197

@@ -149,10 +145,7 @@ public void buildProject( MavenSession session, MavenSession rootSession, Reacto
149145
}
150146
finally
151147
{
152-
if ( scoped )
153-
{
154-
sessionScope.exit();
155-
}
148+
sessionScope.exit();
156149

157150
session.setCurrentProject( null );
158151

maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleStarter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ public void execute( MavenSession session )
107107
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
108108
ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus( session.getProjectDependencyGraph() );
109109
reactorContext =
110-
new ReactorContext( result, projectIndex, oldContextClassLoader, reactorBuildStatus );
110+
new ReactorContext( result, projectIndex, oldContextClassLoader, reactorBuildStatus,
111+
sessionScope.memento() );
111112

112113
String builderId = session.getRequest().getBuilderId();
113114
Builder builder = builders.get( builderId );

maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorContext.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*/
2121

2222
import org.apache.maven.execution.MavenExecutionResult;
23+
import org.apache.maven.session.scope.internal.SessionScope;
2324

2425
/**
2526
* Context that is fixed for the entire reactor build.
@@ -39,13 +40,17 @@ public class ReactorContext
3940

4041
private final ReactorBuildStatus reactorBuildStatus;
4142

43+
private final SessionScope.Memento sessionScope;
44+
4245
public ReactorContext( MavenExecutionResult result, ProjectIndex projectIndex,
43-
ClassLoader originalContextClassLoader, ReactorBuildStatus reactorBuildStatus )
46+
ClassLoader originalContextClassLoader, ReactorBuildStatus reactorBuildStatus,
47+
SessionScope.Memento sessionScope )
4448
{
4549
this.result = result;
4650
this.projectIndex = projectIndex;
4751
this.originalContextClassLoader = originalContextClassLoader;
4852
this.reactorBuildStatus = reactorBuildStatus;
53+
this.sessionScope = sessionScope;
4954
}
5055

5156
public ReactorBuildStatus getReactorBuildStatus()
@@ -68,4 +73,11 @@ public ClassLoader getOriginalContextClassLoader()
6873
return originalContextClassLoader;
6974
}
7075

76+
/**
77+
* @since 3.3.0
78+
*/
79+
public SessionScope.Memento getSessionScopeMemento()
80+
{
81+
return sessionScope;
82+
}
7183
}

maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java

Lines changed: 77 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,35 @@
1919
* under the License.
2020
*/
2121

22-
import java.util.Collection;
23-
import java.util.List;
24-
import java.util.concurrent.ConcurrentHashMap;
25-
import java.util.concurrent.ConcurrentMap;
26-
import java.util.concurrent.CopyOnWriteArrayList;
22+
import java.util.Collections;
23+
import java.util.HashMap;
24+
import java.util.LinkedList;
25+
import java.util.Map;
2726

2827
import com.google.inject.Key;
2928
import com.google.inject.OutOfScopeException;
3029
import com.google.inject.Provider;
3130
import com.google.inject.Scope;
31+
import com.google.inject.util.Providers;
3232

3333
/**
3434
* SessionScope
3535
*/
3636
public class SessionScope
3737
implements Scope
3838
{
39+
/**
40+
* @since 3.3.0
41+
*/
42+
public static class Memento
43+
{
44+
final Map<Key<?>, Provider<?>> seeded;
45+
46+
Memento( final Map<Key<?>, Provider<?>> seeded )
47+
{
48+
this.seeded = Collections.unmodifiableMap( new HashMap<>( seeded ) );
49+
}
50+
}
3951

4052
private static final Provider<Object> SEEDED_KEY_PROVIDER = new Provider<Object>()
4153
{
@@ -48,127 +60,110 @@ public Object get()
4860
/**
4961
* ScopeState
5062
*/
51-
protected static final class ScopeState
63+
private static final class ScopeState
5264
{
53-
private final ConcurrentMap<Key<?>, CachingProvider<?>> provided = new ConcurrentHashMap<>();
65+
private final Map<Key<?>, Provider<?>> seeded = new HashMap<>();
5466

55-
public <T> void seed( Class<T> clazz, Provider<T> value )
56-
{
57-
provided.put( Key.get( clazz ), new CachingProvider<>( value ) );
58-
}
67+
private final Map<Key<?>, Object> provided = new HashMap<>();
68+
}
5969

60-
@SuppressWarnings( "unchecked" )
61-
public <T> Provider<T> scope( Key<T> key, final Provider<T> unscoped )
62-
{
63-
Provider<?> provider = provided.get( key );
64-
if ( provider == null )
65-
{
66-
CachingProvider<?> newValue = new CachingProvider<>( unscoped );
67-
provider = provided.putIfAbsent( key, newValue );
68-
if ( provider == null )
69-
{
70-
provider = newValue;
71-
}
72-
}
73-
return ( Provider<T> ) provider;
74-
}
70+
private final ThreadLocal<LinkedList<ScopeState>> values = new ThreadLocal<>();
7571

76-
public Collection<CachingProvider<?>> providers()
72+
public void enter()
73+
{
74+
LinkedList<ScopeState> stack = values.get();
75+
if ( stack == null )
7776
{
78-
return provided.values();
77+
stack = new LinkedList<>();
78+
values.set( stack );
7979
}
80-
80+
stack.addFirst( new ScopeState() );
8181
}
8282

83-
private final List<ScopeState> values = new CopyOnWriteArrayList<>();
84-
85-
public void enter()
83+
/**
84+
* @since 3.3.0
85+
*/
86+
public void enter( Memento memento )
8687
{
87-
values.add( 0, new ScopeState() );
88+
enter();
89+
getScopeState().seeded.putAll( memento.seeded );
8890
}
8991

90-
protected ScopeState getScopeState()
92+
private ScopeState getScopeState()
9193
{
92-
if ( values.isEmpty() )
94+
LinkedList<ScopeState> stack = values.get();
95+
if ( stack == null || stack.isEmpty() )
9396
{
94-
throw new OutOfScopeException( "Cannot access session scope outside of a scoping block" );
97+
throw new IllegalStateException();
9598
}
96-
return values.get( 0 );
99+
return stack.getFirst();
97100
}
98101

99102
public void exit()
100103
{
101-
if ( values.isEmpty() )
104+
final LinkedList<ScopeState> stack = values.get();
105+
if ( stack == null || stack.isEmpty() )
102106
{
103107
throw new IllegalStateException();
104108
}
105-
values.remove( 0 );
109+
stack.removeFirst();
110+
if ( stack.isEmpty() )
111+
{
112+
values.remove();
113+
}
114+
}
115+
116+
/**
117+
* @since 3.3.0
118+
*/
119+
public Memento memento()
120+
{
121+
LinkedList<ScopeState> stack = values.get();
122+
return new Memento( stack != null ? stack.getFirst().seeded : Collections.<Key<?>, Provider<?>>emptyMap() );
106123
}
107124

108125
public <T> void seed( Class<T> clazz, Provider<T> value )
109126
{
110-
getScopeState().seed( clazz, value );
127+
getScopeState().seeded.put( Key.get( clazz ), value );
111128
}
112129

113130
public <T> void seed( Class<T> clazz, final T value )
114131
{
115-
seed( clazz, new Provider<T>()
116-
{
117-
@Override
118-
public T get()
119-
{
120-
return value;
121-
}
122-
} );
132+
getScopeState().seeded.put( Key.get( clazz ), Providers.of( value ) );
123133
}
124134

125135
public <T> Provider<T> scope( final Key<T> key, final Provider<T> unscoped )
126136
{
127-
// Lazy evaluating provider
128137
return new Provider<T>()
129138
{
130-
@Override
139+
@SuppressWarnings( "unchecked" )
131140
public T get()
132141
{
133-
return getScopeState().scope( key, unscoped ).get();
134-
}
135-
};
136-
}
142+
LinkedList<ScopeState> stack = values.get();
143+
if ( stack == null || stack.isEmpty() )
144+
{
145+
throw new OutOfScopeException( "Cannot access " + key + " outside of a scoping block" );
146+
}
137147

138-
/**
139-
* CachingProvider
140-
* @param <T>
141-
*/
142-
protected static class CachingProvider<T> implements Provider<T>
143-
{
144-
private final Provider<T> provider;
145-
private volatile T value;
148+
ScopeState state = stack.getFirst();
146149

147-
CachingProvider( Provider<T> provider )
148-
{
149-
this.provider = provider;
150-
}
150+
Provider<?> seeded = state.seeded.get( key );
151151

152-
public T value()
153-
{
154-
return value;
155-
}
152+
if ( seeded != null )
153+
{
154+
return (T) seeded.get();
155+
}
156156

157-
@Override
158-
public T get()
159-
{
160-
if ( value == null )
161-
{
162-
synchronized ( this )
157+
T provided = (T) state.provided.get( key );
158+
if ( provided == null && unscoped != null )
163159
{
164-
if ( value == null )
165-
{
166-
value = provider.get();
167-
}
160+
provided = unscoped.get();
161+
state.provided.put( key, provided );
168162
}
163+
164+
return provided;
169165
}
170-
return value;
171-
}
166+
};
172167
}
173168

174169
@SuppressWarnings( { "unchecked" } )

0 commit comments

Comments
 (0)