I have a class ServiceA on project-a:
public class ServiceA {
private ModelA modelA;
public ServiceA(ModelA modelA) {
this.modelA = modelA;
}
}
modelA from other local library (external library). modelA have #Component annotation
when I run this code, cannot found error bean on ModelA. I solve with add #Bean for ModelA on project-a.
Why I should add bean? because the ModelA on external library? Any reference link for I can understand for this case? I want understand for this code. Thank you
The first comment is the most likely answer to your issue;
specifically,
the component scanning that is configured in your project does not include the package that contains the modelA class.
Related
It seems to be a simple question but yet i couldn't find clear answer while searching documentation and forums. I'm migrating from xml to java-based config (Spring 5.1.9). Due to some legacy restrictions in xml config i need to create a bean from some side library's non public class:
SampleClass.class
package side.library
class SampleClass {
//... some code here
}
context.xml
...
<bean id = "sampleId" class "side.library.SampleClass">
...
And this works fine since Spring uses reflection inside and it creates bean without any problems at compile/runtime, but in java-based config usage of such class leads to an access error:
package my.configuration;
import side.library.SampleClass; // 'side.library.SampleClass' is not public in 'side.library'. Cannot be accessed from outside package
#Configuration
public class JavaConfiguration{
#Bean
public SampleClass sampleClass() {
return new SampleClass(); // same error text
}
}
So, what is the proper way to deal with this sutiation? Using reflection libs in #Configuration class to reach this class seems to be a bad idea.
just a workaround: create a wrapper class in the outer project in the same package and use this class in your configuration.
package com.legacy;
public class Wrapper {
private LegacyImpl legacyImpl;
public Wrapper()
this.legacyImpl = new LegacyImpl();
}
public void wrappedMethod() {
this.legacyImpl.wrappedMethod();
}
}
New to spring boot.
We have reusable beans in multiple base dependencies. Since, we need those reusable functionality, we are inheriting those jars in pom.xml.
Ex:
Jar1:
ClassName: UserInfo, RequestInterceptors, ClassName3, ClassName4, ClassNameN.
PackageName: com.somename1.base.comps
Jar2:
ClassName: UserInfo, RequestInterceptors, ClassName3, ClassName4, ClassNameN.
PackageName: com.somename2.base.comps
Since the class name is similar, creates conflict issue, when building.
Unfortunatly, we cannot able to change any class names, since someother teams are using these jar. No permission to create another version of these jars.
Is there any way to include both jar without excluding these conflicting components in #EnableAutoConfiguration or #ComponentScan
annotations?
Could someone share some advice here.
The solution here would be to name your beans. The reason for the conflict would be that the names of the classes are the same. For example:
#Configuration
public class Config{
public com.somename2.base.comps.UserInfo somename2UserInfo(){
return new com.somename2.base.comps.UserInfo();
}
public com.somename1.base.comps.UserInfo somename1UserInfo(){
return new com.somename1.base.comps.UserInfo();
}
}
The beans would then be named somename1UserInfo and somename2UserInfo and you can use these names instead when autowiring, e.g.:
public class SomeImpl{
#Autowired
#Qualifier("somename1UserInfo")
UserInfo userInfo;
/*
* Or you can do this
*/
#Resource(name = "somename1UserInfo")
UserInfo theSameUserInfo
}
This will allow you to autowire whichever bean should be used in whichever class. It may not be ideal to have to declare a qualifier for every place the classes are used, so if one implementation is primarily used, consider looking into the #Primary annotation.
Is it possible to have a bean interface in a project and the implementation of that bean in another project that includes the previous project as a dependency?
I have the following interface:
package com.proj1.util;
import .....;
public interface Notification {
addNotification();
addError();
}
In the same project (i.e. Proj1) I have also the following class:
package com.proj1.util.exception;
import .....;
public class ExceptionHandler extends RuntimeException ... {
private String errorMessage;
#Override
public void handle() {
Util.getBeanInstance(Notification.class).addError(errorMessage);
}
}
Now in the second project I have the actual implementation of Notification that is as follows:
package com.proj2.beans;
#Named
#ConversationScoped
public class NotificationBean implements Notification, Serializable {
private static final long serialVersionUID = 1L;
...
}
This situation leads to an exception in Tomcat with the message "WebBeans context with scope type annotation #ConversationScoped does not exist within current thread"
My proposal was to add a Factory that produces my NotificationBean but it doesn't seem to change much.
package com.proj2.beans.cdi;
import javax.enterprise.inject.New;
import javax.enterprise.inject.Produces;
import com.proj1.util.Notification;
public class NotificationBeanFactory {
#Produces
public Notification create(#New NotificationBean notificationBean) {
return notificationBean;
}
}
The question is how can I use a bean in a project in which I have only it's interface while the bean implementation is in another project. Is it possible?
The exception suggests there is no running conversation so I would start by determining when do you attempt to use #ConversationScoped bean and from which class.
Your code pieces indicate that ExceptionHandler class calls a magical formula which we do not know anything else about:
Util.getBeanInstance(Notification.class).add(...);
Trying to use this when there is no active conversation might lead to the exception you see. Therefore you could #Inject ExceptionHandler into NotificationBean so that you only ever use it while there is active conversation.
As for the Weld question regarding interface and impl in different projects; it is possible. in your proj2 Weld will simply identify a bean NotificationBean and amongst it's types there will also be Notification hence you can then #Inject Notification.
It might not work the other way round though - in proj1 you cannot #Inject Notification because proj1 itself does not have any bean which would implement that interface.
I'm developing an Eclipse RCP application based on 4.4 Luna version.
I have the following classes:
public class NewProjectDialog extends TitleAreaDialog {
#Inject
private ProjectManager projectManager;
// some code
}
and
#Creatable
#Singleton
public class ProjectManager {
// some Code
}
When I run the application and open NewProjectDialog the following exception is thrown:
org.eclipse.e4.core.di.InjectionException: org.eclipse.e4.core.di.
InjectionException: Unable to process "NewProjectDialog.projectManager":
no actual value was found for the argument "ProjectManager".
Apart #Creatable annotation must I do something more to make Eclipse DI instantiate this class when it cannot find it in the context?
I have also face the same issue and the answer already given by greg-449 is in the comment section of the question is correct. Yes, it is problem in injecting/creating the fields of such objects.
I've been looking all over Google to find some useful information on how to use Guice/Spring DI in Play Framework 2.1
What I want to do is to Inject several Services in some DAO's and vice versa.
Just need some clarification on this - With play 2.1, do you have to use an # annotation within the routes file for DI?
I've looked at this guide here - https://github.com/playframework/Play20/blob/master/documentation/manual/javaGuide/main/inject/JavaInjection.md
and applied the following steps creating a Global class in app and adding the GUICE dependencies in Build.scala but keep on getting a null pointer exception when invoking on the injected object.
Has anyone been able to get DI working in Play 2.1 using Guice? I've seen examples across the internet but they all seem to be using DI within the controller.
I noticed you are using Java. Here is how I got it to work for injecting into a controller.
First, I created the following 4 classes :
MyController:
package controllers;
import play.mvc.*;
import javax.inject.Inject;
public class MyController extends Controller {
#Inject
private MyInterface myInterface;
public Result someActionMethodThatUsesMyInterface(){
return ok(myInterface.foo());
}
}
MyInterface:
package models;
public interface MyInterface {
String foo();
}
MyImplementation2Inject:
package models;
public class MyImplementation2Inject implements MyInterface {
public String foo() {
return "Hi mom!";
}
}
MyComponentModule:
package modules;
import com.google.inject.AbstractModule;
import models.MyInterface;
import models.MyImplementation2Inject;
public class ComponentModule extends AbstractModule {
#Override
protected void configure() {
bind(MyInterface.class).
to(MyImplementation2Inject.class);
}
}
Now the final part, that took me a silly long time to figure out, was to register the module. You do this by adding the following line to the end of the application.conf file, which is located in the conf directory:
play.modules.enabled += "modules.MyComponentModule"
I hope this was helpful to you. :)
I use cake pattern and my own version of Global overriding getControllerInstance
https://github.com/benjaminparker/play-inject
Cheers
Ben
Sorry, this is a late response, but here's our example
https://github.com/typesafehub/play-guice
Have you tried using some different approach to DI than Guice?
We also tried implementing a project with Guice or Spring but ended in registering our dependencies in objects that implement trait such as:
trait Registry {
def userDao: UserDao
...
}
object Registry {
var current: Registry = _
}
object Environnment {
object Dev extends Registry {
val userDao = ...
//implement your environment for develpment here
}
object Test extends Registry {
val userDao = ...
//implement your ennviroment for tests here e.g. with mock objects
}
}
Another good approach wich might fit for you is the cake pattern (just google for it).