Eclipse - can you navigate to an injected bean - eclipse

I am using the STS eclipse IDE version 2.8
Is it possible to navigate directly to a class from the bean name ?
IE to the class whose bean name is 'foo.bar in the example below:
public class SomeClass() {
#Autowired(required=true)
#Qualifier("foo.bar")
private FooServive myFooService;
...
}
I know I can get to it from the Spring Explorer tab but I want to miss out the middle man.

...often, also the "Spring Beans references search" is quite helpful. It provides an overview of all references to the given bean name; typically you'll get the class definition, the XML definition and uses in dependency injection.
Standard keybinding for this is CTRL-SHIFT-g.

You can use Alt-F7 to Java-search on "foo.bar". It will bring up the bean definition so named (at least when using XML configuration files). At the bean definition you can press F3 on the value of the class attribute, which will bring you to the class definition itself. You have to have the Spring Nature enabled of course.

Related

Extension for showing autowired beans in VS Code

Supossedly, I have a class, called CustomerService, declared as #Service. Furthermore, I also a controller, called CustomerRestController, declared as #RestController.
By using IntelliJ, I can easily recognize
which class is defined as a bean
which bean is autowired
By using VS Code, I am only able to see like following
Is there any extension that makes VS Code show the thing like IntelliJ?

Spring data inject repository without explicit type

I have a service that needs to use Neo4jRepository (regular repository provider by spring data).
public class SomeServiceBean<T>{
#Autowired
private Neo4jRepository<T,Long> Neo4jRepository;
}
This class will generate en error:
expected single matching bean but found 2: systemUserRepository,systemClaimRepository
The problem is that systemClaimRepository and systemUserRepository is extending Neo4jRepository<T,Long> as a bean without implementation.
Spring see systemClaimRepository and systemUserRepository as Neo4jRepository<T,Long> because they are extending it.
Is there anyway to inject Neo4jRepository<T,Long>?
Thanks
No how should this work?
You have two beans that match the interface and Spring does not know which implementation to inject.

Spring bean name clash Hibernate/Proguard?

Consider a multi-module Java/Scala Maven application to obfuscate. It's using the classic Spring approach of Hibernate/JPA/Spring Data JPA/services/repositories/.... All using xml configuration files.
What has been done
Keep intact class names mentioned in web.xml and Spring xml files.
Keep intact the package names used in all < context:component-scan.../ > + bean name generator to guarantee unique bean names.
Keep intact classes referenced by introspection.
Don't use mixed case class names because Spring bean names are case-insensitive.
But whatever I try, I continue to clash bean names with what I think is Hibernate. An example of the error:
Caused by: org.hibernate.DuplicateMappingException: Duplicate collection role mapping com.bar.project.Definition.d
at org.hibernate.cfg.Configuration$MappingsImpl.addCollection(Configuration.java:2739)
at org.hibernate.cfg.annotations.CollectionBinder.bind(CollectionBinder.java:561)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2084)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:895)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:728)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3625)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3579)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1381)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1786)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915)
... 32 more
Proguard indeed made a class named 'd'. Which was duly renamed to something like 'BeanFFEECC' using the bean name generator.
class BeanNameGenerator extends DefaultBeanNameGenerator {
override def generateBeanName(definition: BeanDefinition, registry: BeanDefinitionRegistry): String = {
val id = Integer.toHexString(super.generateBeanName(definition, registry).hashCode).toUpperCase
var proposedName = "Bean" + id
while (registry.isBeanNameInUse(proposedName)) {
proposedName += "0"
}
proposedName
}
}
Unless I misunderstood the role of a Spring bean name generator, I would assume this should have fixed the name conflict. The very same error pops up when defining a class name dictionary for Proguard. To avoid it to generate one-letter class names.
Is there anybody who knows what problem I'm having here ?
FOUND IT ! Apparently Proguard will by default rename private fields. Which is common practise for entity classes. And since I've put the JPA annotations on the fields, you'll get a field named 'd' pretty frequently.
Adding the role to the configuration fixed that issue.
-keep class com.bar.model.** {
<fields>;
<methods>;
}
Before that it was
-keep class com.bar.model.**

How to use Injection Annotation

Until to now i use (like beginner) JSF. Usually I make xhtml page and backend bean. And in backing bean I use annotation like #ManagedBean, #SessionScoped, #Application and so on. i think that is annotation for javax.faces.bean, if it is correctly that is faces annotations.
Bath I find one tutorial on internet where one guy use annotation like #Model an most interesting in backand bean He uses the #Inject annotation. I find that is very useful. He use injection for Logger class and in same bean can use methods from that class. Something like these:
#Model
public class FileUploadBean {
#Inject Logger log;
private Part file;
public void upload(){
...
}
}
Are there he use enterprise java, maybe CDI and how I can use this annotation. Because when i write #Inject in my Backing bean have message that is ambiguous annotation.
What i have to know and about what?
I working with eclipse and glassfish!
You're talking about the javax.enterprise.Inject annotation. See the cdi tag wiki page for some basic information. The only thing you'd need to have is the corresponding import statement.
A word of warning: if you already have a project with JSF beans, note that most scope annotations (#SessionScoped, #RequestScoped, ...) have a CDI equivalent that has the same name. Make sure you import the correct annotation or you'll find that your "session bean" suddenly has only request scope.
See also:
Weld Reference
JEE6 CDI Tutorial

cannot find my bean using the InitialContext.lookup() method

I have tried to use struts 1.3 API to make a small application with EJB 3.0. Unfortunatelly i cannot use the #EJB annotation to call my bean object from inside my action class. I have solved this problem using different workarounds ( the first one is to use my global jndi name of my bean and the other is to call another class first and use the #EJB annotation from that class). Still these two workarounds have significant disadvantages. I would like to call my EJB directly from my action class. I have read plenty examples using the "java:comp/env/beanName" JNDI name but still haven't figure out how to do it and get name not found axception.
Let the full name of the local EJB class be the com.ejb.myEjbPackage.MyEJBLocal, how can i call it using the context lookup? (can i do it without modifying any of the web.xml and sun-web.xml descriptors?)
I am using glassfish server and Netbeans IDE.
Thank you in advance
#EJB won't work in a standard pojo it can only be done in a managed object (i.e. another session bean)
So...
Here's your bean
#Stateless(mappedName="beanName")
public class beanName implements beanNameRemote {
Here's your lookup
Context context = new InitialContext(); //default lookup pulls from jndi properties file
context.lookup("beanName");
You can do some further reading on the mappedName to see if you want to use it or not.
I found the answer :
If you cannot use the EJB annotation in the class you want to call the bean then :
If you don't want to mess with XML descriptors to define your bean , you have to do it in the bean class itself.
Hence i used the following annotation in the GameBean class
#Stateless
#EJB(name="ejb/GameBean",beanInterface=GameBeanLocal.class,beanName="GameBean")
public class GameBean implements GameBeanLocal {.....
The beanName is optional. The annotation must be declared in the line ABOVE the declaration of the class.
Then, in order to call the bean from the other class you can do
InitialContext ic = new InitialContext();
ic.lookup("java:comp/env/ejb/GameBean");