Guice dependency injection in the SFS extension

Post here your questions about SFS2X. Here we discuss all server-side matters. For client API questions see the dedicated forums.

Moderators: Lapo, Bax

Gavrus
Posts: 1
Joined: 20 Oct 2018, 18:32

Guice dependency injection in the SFS extension

Postby Gavrus » 20 Oct 2018, 18:58

Hi, im trying to use DI with Guice in the extension plugin, but extension loading fails with exception:

Code: Select all

Exception: java.lang.NoSuchMethodError
Message: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
Description: An error occurred while reloading extension: Survival in { Zone: Survival }
The new extension might not function properly.
+--- --- ---+
Stack Trace:
+--- --- ---+
com.google.inject.TypeLiteral.getParameterTypes(TypeLiteral.java:278)
com.google.inject.spi.InjectionPoint.forMember(InjectionPoint.java:115)
com.google.inject.spi.InjectionPoint.<init>(InjectionPoint.java:82)
com.google.inject.spi.InjectionPoint.forConstructorOf(InjectionPoint.java:289)
com.google.inject.internal.ConstructorBindingImpl.create(ConstructorBindingImpl.java:115)
com.google.inject.internal.InjectorImpl.createUninitializedBinding(InjectorImpl.java:706)
com.google.inject.internal.UntargettedBindingProcessor$1.visit(UntargettedBindingProcessor.java:54)
com.google.inject.internal.UntargettedBindingProcessor$1.visit(UntargettedBindingProcessor.java:36)
com.google.inject.internal.UntargettedBindingImpl.acceptTargetVisitor(UntargettedBindingImpl.java:49)
com.google.inject.internal.UntargettedBindingProcessor.visit(UntargettedBindingProcessor.java:35)
com.google.inject.internal.UntargettedBindingProcessor.visit(UntargettedBindingProcessor.java:27)
com.google.inject.internal.BindingImpl.acceptVisitor(BindingImpl.java:99)
com.google.inject.internal.AbstractProcessor.process(AbstractProcessor.java:54)
com.google.inject.internal.InjectorShell$Builder.build(InjectorShell.java:186)
com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103)
com.google.inject.Guice.createInjector(Guice.java:87)
com.google.inject.Guice.createInjector(Guice.java:69)
com.google.inject.Guice.createInjector(Guice.java:59)
Extension.SurvivalExtension.init(SurvivalExtension.java:12)
com.smartfoxserver.v2.entities.managers.SFSExtensionManager.createExtension(SFSExtensionManager.java:303)
com.smartfoxserver.v2.entities.managers.SFSExtensionManager.reloadExtension(SFSExtensionManager.java:533)
com.smartfoxserver.v2.entities.managers.SFSExtensionManager$ExtensionFileChangeListener.fileChanged(SFSExtensionManager.java:111)
org.apache.commons.vfs.events.ChangedEvent.notify(ChangedEvent.java:34)
org.apache.commons.vfs.provider.AbstractFileSystem.fireEvent(AbstractFileSystem.java:519)
org.apache.commons.vfs.provider.AbstractFileSystem.fireFileChanged(AbstractFileSystem.java:487)
org.apache.commons.vfs.impl.DefaultFileMonitor$FileMonitorAgent.check(DefaultFileMonitor.java:647)
org.apache.commons.vfs.impl.DefaultFileMonitor$FileMonitorAgent.access$200(DefaultFileMonitor.java:418)
org.apache.commons.vfs.impl.DefaultFileMonitor.run(DefaultFileMonitor.java:373)
java.lang.Thread.run(Unknown Source)


Extension builds as Uber jar with maven shade plugin - pom file example:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>test_sfs_di</artifactId>
    <version>1.0</version>

    <build>
        <finalName>TestDiExtension</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <outputDirectory>C:/Path_to_smartfox/SmartFoxServer_2X/SFS2X/extensions/TestDi</outputDirectory>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.smartfox</groupId>
            <artifactId>sfs2x</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>com.smartfox</groupId>
            <artifactId>sfs2x-core</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>4.2.1</version>
        </dependency>
    </dependencies>
</project>


Test source code of the extension:

Code: Select all

package Extension;
import com.google.inject.Singleton;

@Singleton
public class Sing
{
    public void foo()
    {
        System.out.println("Sing");
    }
}


Code: Select all

package Extension;
import com.google.inject.Inject;

public class Service
{
    @Inject private Sing sing;

    public void run()
    {
        sing.foo();
    }
}


Code: Select all

package Extension;
import com.google.inject.AbstractModule;

public class IOC extends AbstractModule
{
    @Override
    protected void configure()
    {
        bind(Sing.class).asEagerSingleton();
    }
}


Code: Select all

package Extension;
import com.google.inject.*;
import com.smartfoxserver.v2.extensions.SFSExtension;

public class TestDiExtension extends SFSExtension
{
    @Override
    public void init()
    {
        Injector injector = Guice.createInjector(new IOC());
        Service service = injector.getInstance(Service.class);
        service.run();     
    }
}


It looks like the promlem with ClassLoader, but how to fix it?
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: Guice dependency injection in the SFS extension

Postby Lapo » 22 Oct 2018, 08:15

Hi,
I am not sure it's a class loading issue.

According to the error you've reported:

Code: Select all

Exception: java.lang.NoSuchMethodError
Message: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V
Description: An error occurred while reloading extension: Survival in { Zone: Survival }
The new extension might not function properly.

The Guice runtime is trying to execute a method whose signature is not found on the Preconditions class. (which is found)

Usually a NoSuchMethodError occurs when you compile the code against a certain version of a library but then deploy another version of such library, resulting in mismatches such as this one.

I'd recommend double checking that you're using the same release of the Guice in your dev environment and for deployment.

Hope it helps
Lapo
--
gotoAndPlay()
...addicted to flash games

Return to “SFS2X Questions”

Who is online

Users browsing this forum: Google [Bot] and 53 guests