Skip to content

Commit

Permalink
When @parameters are bound by @provides methods, attempt to invoke
Browse files Browse the repository at this point in the history
them statically via reflection rather than use the internal provider
(which may not have been initialized at this point)
  • Loading branch information
mcculls committed Jan 3, 2022
1 parent a45a6cd commit e5165a2
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 11 deletions.
71 changes: 71 additions & 0 deletions org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/Guice4.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
*******************************************************************************/
package org.eclipse.sisu.inject;

import java.security.AccessController;
import java.security.PrivilegedAction;

import javax.inject.Provider;

import com.google.inject.Binding;
import com.google.inject.Scopes;
import com.google.inject.spi.InstanceBinding;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProvidesMethodBinding;

/**
* Utility methods for dealing with changes in the Guice 4.0 SPI.
Expand Down Expand Up @@ -75,6 +80,22 @@ public final class Guice4
hasOldScopesSingleton = false;
}
HAS_OLD_SCOPES_SINGLETON = hasOldScopesSingleton;

boolean hasProvidesMethodSpi;
try
{
// in Guice4 @Provides Method providers implement ProvidesMethodBinding
hasProvidesMethodSpi = ProvidesMethodBinding.class instanceof Class<?>;
}
catch ( final Exception e )
{
hasProvidesMethodSpi = false;
}
catch ( final LinkageError e )
{
hasProvidesMethodSpi = false;
}
HAS_PROVIDES_METHOD_SPI = hasProvidesMethodSpi;
}

// ----------------------------------------------------------------------
Expand All @@ -87,6 +108,8 @@ public final class Guice4

private static final boolean HAS_OLD_SCOPES_SINGLETON;

private static final boolean HAS_PROVIDES_METHOD_SPI;

static final Object NIL = new Object();

// ----------------------------------------------------------------------
Expand Down Expand Up @@ -130,6 +153,54 @@ public static Provider<?> getProviderInstance( final ProviderInstanceBinding<?>
return HAS_USER_SUPPLIED_PROVIDER ? binding.getUserSuppliedProvider() : binding.getProviderInstance();
}

/**
* Attempts to invoke the given binding statically; returns {@code null} if the binding isn't static.
*
* @param binding The binding
* @return Statically bound instance
*/
public static Object invokeStaticBinding( final Binding<?> binding )
{
if ( binding instanceof InstanceBinding<?> )
{
return ( (InstanceBinding<?>) binding ).getInstance();
}
if ( binding instanceof ProviderInstanceBinding<?> )
{
final Provider<?> provider = getProviderInstance( (ProviderInstanceBinding<?>) binding );
if ( HAS_PROVIDES_METHOD_SPI && provider instanceof ProvidesMethodBinding )
{
try
{
// attempt to invoke the @Provides Method statically via reflection
final ProvidesMethodBinding providesMethod = (ProvidesMethodBinding) provider;
if ( !providesMethod.getMethod().isAccessible() )
{
AccessController.doPrivileged( new PrivilegedAction<Void>()
{
public Void run()
{
providesMethod.getMethod().setAccessible( true );
return null;
}
} );
}
return providesMethod.getMethod().invoke( providesMethod.getEnclosingInstance() );
}
catch ( final Exception e )
{
return null;
}
catch ( final LinkageError e )
{
return null;
}
}
return provider.get();
}
return null;
}

/**
* Returns a lazy provider that only uses the binding once and caches the result.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@
import com.google.inject.spi.ElementVisitor;
import com.google.inject.spi.Elements;
import com.google.inject.spi.InjectionRequest;
import com.google.inject.spi.InstanceBinding;
import com.google.inject.spi.PrivateElements;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderLookup;
import com.google.inject.spi.RequireExplicitBindingsOption;
import com.google.inject.spi.StaticInjectionRequest;
Expand Down Expand Up @@ -284,15 +282,7 @@ private void makeJitBindingsExplicit()

private void mergeParameters( final Binding<?> binding )
{
Object parameters = null;
if ( binding instanceof InstanceBinding<?> )
{
parameters = ( (InstanceBinding<?>) binding ).getInstance();
}
else if ( binding instanceof ProviderInstanceBinding<?> )
{
parameters = Guice4.getProviderInstance( (ProviderInstanceBinding<?>) binding ).get();
}
Object parameters = Guice4.invokeStaticBinding( binding );
if ( parameters instanceof Map )
{
properties.add( (Map<?, ?>) parameters );
Expand Down

0 comments on commit e5165a2

Please sign in to comment.