Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to find beans from Guice framework #2210

Open
udalrich opened this issue Sep 6, 2016 · 7 comments
Open

Unable to find beans from Guice framework #2210

udalrich opened this issue Sep 6, 2016 · 7 comments

Comments

@udalrich
Copy link

udalrich commented Sep 6, 2016

I am using atmosphere-runtime 2.4.5, atmosphere-play 2.3.0 and atmosphere-guice 2.4.3.

I have a play controller which is created by Guice with this signature:

@Singleton
public class AsyncController extends Controller {
    @Inject
    public AsyncController(ActorSystem actorSystem,
                           ExecutionContextExecutor exec,
                           ApplicationLifecycle lifecycle,
                           MyClass mediator) {
        <stuff>
      AtmosphereCoordinator.instance().discover(MyAtmosphereController.class).ready();
   }
}

Guice finds MyClass and creates the object. The AtmosphereCoordinator call throws an exception:

2016-09-06 12:44:38,520 [WARN] from org.atmosphere.annotation.ManagedServiceProcessor in application-akka.actor.default-dispatcher-8 -
com.google.inject.ConfigurationException: Guice configuration errors:

  1. No implementation for akka.actor.ActorSystem was bound.
    while locating akka.actor.ActorSystem
    for parameter 0 at me.MyClassImpl.(MyClassImpl.java:29)
    while locating me.MyClass
    for parameter 0 at me.MyAtmosphereController.(MyAtmosphereController.java:29)
    while locating me.MyAtmospherController

1 error
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1042) [guice-4.0.jar:na]
at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1001) [guice-4.0.jar:na]
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051) [guice-4.0.jar:na]
at org.atmosphere.guice.GuiceObjectFactory.newClassInstance(GuiceObjectFactory.java:71) ~[atmosphere-guice-2.4.3.jar:2.4.3]
at org.atmosphere.cpr.AtmosphereFramework.newClassInstance(AtmosphereFramework.java:3060) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.annotation.ManagedServiceProcessor.handle(ManagedServiceProcessor.java:61) ~[atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.cpr.AnnotationHandler.handleAnnotation(AnnotationHandler.java:94) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.cpr.DefaultAnnotationProcessor$BytecodeBasedAnnotationProcessor$1.reportTypeAnnotation(DefaultAnnotationProcessor.java:383) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.util.annotation.AnnotationDetector.readAnnotations(AnnotationDetector.java:695) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.util.annotation.AnnotationDetector.readAttributes(AnnotationDetector.java:672) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.util.annotation.AnnotationDetector.detect(AnnotationDetector.java:543) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.util.annotation.AnnotationDetector.detect(AnnotationDetector.java:510) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.util.annotation.AnnotationDetector.detect(AnnotationDetector.java:387) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.cpr.DefaultAnnotationProcessor$BytecodeBasedAnnotationProcessor.scan(DefaultAnnotationProcessor.java:402) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.cpr.DefaultAnnotationProcessor.scan(DefaultAnnotationProcessor.java:227) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.cpr.AtmosphereFramework.autoConfigureService(AtmosphereFramework.java:2836) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.cpr.AtmosphereFramework.init(AtmosphereFramework.java:903) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.cpr.AtmosphereFramework.init(AtmosphereFramework.java:825) [atmosphere-runtime-2.4.5.jar:2.4.5]
at org.atmosphere.play.AtmosphereCoordinator.ready(AtmosphereCoordinator.java:76) [atmosphere-play-2.3.0.jar:na]

MyAtmosphereController is declared as

@ManagedService(path = "/some/path")
 public class LogMessageController {

    @Inject
    public MyAtmosphereController(@NonNull MyClass myClass) {
      <stuff>
    }   
 }

Guice is clearly finding MyClass, as it is being passed to the AsyncController constructor. What needs to be done to enable it to find the class within the Atmosphere framework?

I looked in the documentation, but all I found was how to use Guice (which I am doing) or write my own Injectables and tell the CDI about them. But Guice can already find the classes.

@GedMarc
Copy link

GedMarc commented Jul 20, 2018

Atmosphere Guice plugin doesn't work at all in any real world situation, gotta do it yourself... the library should actually be pulled or marked as deprecated.

private static final String ContextAttributeName = "AtmosphereServlet";

module.bind(AtmosphereFramework.class)
  .toProvider(() ->
			  {
				  ServletContext servletContext = ServletContextFactory.getDefault()
																	   .getServletContext();
				  AtmosphereServlet servlet = null;
				  try
				  {
					  servlet = (AtmosphereServlet) servletContext.getServlet(ContextAttributeName);
				  }
				  catch (ServletException e)
				  {
					  log.log(Level.SEVERE, "Unable to get atmosphere framework from Servlet property", e);
				  }
				  return servlet.framework();
			  });
module.bind(AtmosphereResourceFactory.class)
  .toProvider(() ->
			  {

				  try
				  {
					  ServletContext servletContext = ServletContextFactory.getDefault()
																		   .getServletContext();
					  AtmosphereServlet servlet = (AtmosphereServlet) servletContext.getServlet(ContextAttributeName);
					  AtmosphereFramework framework = servlet.framework();
					  return framework.atmosphereFactory();
				  }
				  catch (Exception e)
				  {
					  log.log(Level.SEVERE, "Unable to get Atmosphere Resource Factory", e);
					  return new DefaultAtmosphereResourceFactory();
				  }
			  });
module.bind(BroadcasterFactory.class)
  .toProvider(() ->
			  {
				  AtmosphereServlet servlet = null;
				  try
				  {
					  servlet = (AtmosphereServlet) ServletContextFactory.getDefault()
																		 .getServletContext()
																		 .getServlet(ContextAttributeName);
				  }
				  catch (ServletException e)
				  {
					  log.log(Level.SEVERE, "Unable to get atmosphere Servlet from Servlet property. Change the static field ", e);
				  }
				  return servlet.framework()
								.getBroadcasterFactory();
			  });
module.bind(MetaBroadcaster.class)
  .toProvider(() ->
			  {
				  AtmosphereServlet servlet = null;
				  try
				  {
					  servlet = (AtmosphereServlet) ServletContextFactory.getDefault()
																		 .getServletContext()
																		 .getServlet(ContextAttributeName);
				  }
				  catch (ServletException e)
				  {
					  log.log(Level.SEVERE, "Unable to get atmosphere Servlet from Servlet property. Change the static field ", e);
				  }
				  return servlet.framework()
								.metaBroadcaster();
			  });
log.config("Atmosphere Successfully Bound");

@jfarcand
Copy link
Member

@GedMarc Have you try latest .21 by any chance?

@GedMarc
Copy link

GedMarc commented Jul 26, 2018

Yep, same problems, not fixed.

Either way though it's no longer valid - Atmosphere went spring boot which has a completely different injection mechanism that doesn't follow any JSR so plugging Guice on top of it is really not a good idea by any means. With the official release of javax.websocket as the official WS API for Java, and the removal of the older HttpUrlConnection and etc packages it can never be modular without major MAJOR modifications.

Much better way straight out Java is to now just annotate with the core annotations @serverendpoint and @ClientEndpoint, plus core Java now has a client to connect direct from client to web socket. These are do-able without any CDI (piss off weld) and are extremely DI friendly.

With HTTP2 this is also the protocol standard,
So in a nutshell, No point in ever using Atmosphere again for any project JDK 8 and up, it was great and did the job when the mechanism was still under development and no one could choose between comet, meteor, long poll, or WS, but that time is over now, it's part of the JDK and is standardized globally as part of w3.

Thanks tho.

@jfarcand
Copy link
Member

@GedMarc OK I disagree with your statement but it is your choice. As the creator of Atmosphere, I still think you get much more than what you have described below. Guice support is fixed BTW with the new property added in .21...You need to bind yourself Atmosphere components.

@pratyoosh
Copy link

@jfarcand A practical problem that i ran into is atmosphere-guice depends on atmosphere-jersey which has a jersey 1.x dependency, this renders all of these modules useless for anyone using Jersey 2.x (majority of people writing a new project)

@jfarcand
Copy link
Member

jfarcand commented Jan 6, 2019

@pratyoosh If you make that dependency optional, does it help? Contribution welcomed!!!

@jfarcand jfarcand reopened this Jan 6, 2019
@pratyoosh
Copy link

pratyoosh commented Jan 17, 2019

@jfarcand i did tried that option & it didn't worked very well for me due to jersey imports.

I settled with a not such optimal option of getting injector from servletcontext & using injector.injectMembers to inject guice managed objects in my atmosphere broadcaster.
I will give it a try in the next couple of months to come up with something cleaner.

Injector existingInjector = (Injector)config.framework().getServletContext().getAttribute(Injector.class.getName());
existingInjector.injectMembers(this);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants