How to find out how a specific bean is wired in Spring - java

I have a spring application (A) which uses a transient dependency (B) which in itself is based on Spring as well.
So to summarize, war A & jar B are both spring projects. B is a dependency of A.
One of the attributes of a class in B is decorated in the following way
#Resource(name="thisIsTheTargetRef")
private String hardToFindMe;
I went through the application context files of A & B but I do not find a declaration of a bean with the id 'thisIsTheTargetRef'. But somehow the logs show that the .hardToFindMe. attr gets wired with 'thisIsTheTargetRef' bean. I search through both the A & B projects including all other dependencies to see if this is getting picked up from somewhere else. No dice. I even inspected the Component-scan packages but with no luck. I also did a hard text search for 'thisIsTheTargetRef' in both A & B including the dependency projects. I still don't find it.
Here is a log snippet showing that the bean is still getting wired.
[#|2014-01-27T18:23:16.654+0000|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=10;_ThreadName=Thread-3;|77875 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory {} null - Returning cached instance of singleton bean 'thisIsTheTargetRef'
|#]
[#|2014-01-27T18:23:46.640+0000|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=10;_ThreadName=Thread-3;|18:23:46,639 INFO [XmlWebApplicationContext:1332] Bean 'thisIsTheTargetRef' of type [class org.springframework.jndi.JndiObjectFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
|#]
It does appears that I'm missing something here. There might have been a dependency that I have missed looking into and my eyes are just fooling me. But any other obvious places that I should look at?
If not, based on the logs, XmlWebApplicationContext:1332 is referred as the location for the bean. How can I debug to find out where it is getting picked from? Thanks.

You might be lucky by defining a watch/breakpoint on the field you know where it is injected. During the debugging you should get a stop during the autowiring process and you will see which class is wired. This should help identifing it and then check occurences for this class.
I'm not sure if you can directly find out from where this bean is loaded. One hint should be either the annotationprocessor or xmlprocessor.

Related

I am reciving a bean creation error with my security config class for spring security

these are the errors i am getting.. i can't seem to figure out why. i've rewritten the code more than a couple of times and went through the lessons. can someone please take a look? I am working on a basic spring project.
-Error creating bean with name 'securityConfig'
-Error creating bean with name 'usersMapper'
-Mapped Statements collection already contains value for com.udacity.jwdnd.course1.cloudstorage.mapper.UsersMapper.getUser
varun
In the interface UsersMapper, you have two methods getUser(). Even if the signature are different, it seems to be not supported.
I suggest to rename the getUser(int id) by getUserById(int id) to solve the issue.

sql scripts not working when JobRegistryBeanPostProcessor bean is used

I have a Spring batch application which uses some sql scripts to initialise the database.
When I extend the application by Spring Batch functionality I need to instantiate the JobRegistryBeanPostProcessor bean in order to use JobRegistry.
I use a similar method as in https://github.com/jbbarquero/spring-batch-sample/blob/master/src/main/java/com/malsolo/springframework/batch/sample/BatchConfiguration.java
However with such addition I have got a problem - sql scripts are not executed anymore.
In the log output I mentioned such new INFO messages with different bean names (XXX) :
] trationDelegate$BeanPostProcessorChecker : Bean XXX is not eligible
for getting processed by all BeanPostProcessors (for example: not
eligible for auto-proxying)
Is there an approach to resolve the problem aforementioned ?
There is a following solution to the problem:
instead of instantiating the JobRegistryBeanPostProcessor bean, directly register the job in the jobRegistry as proposed in https://stackoverflow.com/a/53381283/6931863
Such solution enables initialisation of Database from data.sql as well as stopping jobs using jobOperator.stop.

No bean named but bean is defined

I'm working on an update version of grail-oauth-plugin that support last spring-oauth
My plugin version works good and I have implemented a workin oauth2 server.
But now I want to add a custom-grant defined like this
def doWithSpring = {
myTokenGranter(MyTokenGranter)
xmlns oauth:"http://www.springframework.org/schema/security/oauth2"
oauth.'authorization-server'( /* ... many definitions here ... */){
/* ... many definitions here ... */
oauth.'custom-grant'('token-granter-ref': "myTokenGranter")
}
}
But I get an exception telling me:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'myTokenGranter'
But the bean myTokenGranter is defined as you can see. And If I remove the custom-grant definition the project starts and I can access the myTokenGranter bean.
Looking to a fullstack trace I see that the exception occur in the spring oatuh2 server bean definition parse AuthorizationServerBeanDefinitionParser.java in the line where it try to find my bean
parserContext.getRegistry().getBeanDefinition(customGranterRef);
where customGranterRef = "myTokenGranter"
so I suspect there is a bug in Spring Ouath or in Grails BeanBuilder that does not let my "myTokenGranter" to be visible in the server parser. Or making some error in grails bean definition DSL.
Thank you for your interest.
Debugging the app more deeply I have found that the problem probably is in how grails BeanBuilder work in translating namespaced spring DSL.
If I debug the point where my bean is checked (in AuthorizationServerBeanDefinitionParser.java)
at row
parserContext.getRegistry().getBeanDefinition(customGranterRef);
if I check che result of
parserContext.getRegistry().getBeanDefinitionNames()
it show me only this beans
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.annotation.internalPersistenceAnnotationProcessor
org.springframework.aop.config.internalAutoProxyCreator
org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0
org.springframework.transaction.interceptor.TransactionInterceptor#0
org.springframework.transaction.config.internalTransactionAdvisor
oauth2TokenGranter
oauth2AuthorizationCodeServices
oauth2AuthorizationRequestManager]
And not all other decleared beans...
The problem exist even if I move the ouath server declaration inside resources.xml, keeping my custom token granter bean declaration inside resources.groovy.
But the problem solves if I move the custom token bean declaration inside resources.xml.
I don't really know how the BeanBuilder DSL works, but it seems like the problem is there if there is a problem (your example works just fine in XML). Can you do it in two steps, so the bean definition for myTokenGranter is definitely available when the OAuth2 namepsace is handled?
Solved hacking Spring Security Oauth
see this commit

Logging Spring bean creation / dependency injection

I'm looking for a way to set up Log4j (or any other logger) so that I can see in log whenever Spring creates a bean or sets a bean property. Eg. something like this:
1:00:00 Creating bean Foo (Foo#ef5c94)
1:00:01 Creating bean Bar (Bar#147a87e)
1:00:02 Setting bean Foo (Foo#ef5c94) to Bar (Bar#147a87e)
(...)
Is this easily possible? I'm using Spring 2.5.6 (no choice there :/ ) and Log4j (version doesn't matter I expect).
Looks like org.springframework.beans.factory.support.DefaultListableBeanFactory logger is the best you can get.
Also simply try turning on ALL logging level for the whole org.springframework - maybe you'll find something more useful.
You can use a Log4jConfigListener in your web.xml:
http://cristianvrabie.blogspot.com/2008/09/spring-commonslogging-and-log4j.html

Constructor arguments in autowiring sources

What exactly causes this?
org.springframework.beans.factory.NoSuchBeanDefinitionException: \
No unique bean of type [fi.utu.keycard.business.KeyCardManager] \
is defined: expected single matching bean but found 2: \
[dataBaseTarget, database]
// etc. (rest of Stack Trace is irrelevant)
What I need is autowiring 3 things: validator, ldap connection and database connection.
I call it:
#Controller
Controller(KeyCardManager database,
LdapPersonDao personManager,
GiveFormValidator validator)
The error seems to cause by another bean, if I change the order of these parameters. I have no signing-in, so I dont have UserDetails or so.
The fix is probably something like this:
public Controller(
#Qualifier("beanQualifier") KeyCardManager database,
LdapPersonDao personManager,
GiveFormValidator validator
)
Since there are apparently two beans of type KeyCardManager in your application context, you need to tell the context which one to wire.
Unfortunately the #Qualifier mechanism doesn't work with bean names, you must either annotate the actual bean with a corresponding #Qualifier or add a <qualifier> element to the XML bean definition.
The #Resource annotation works with bean names, but it doesn't support Constructor parameters (that's not Spring's fault, it's a JSR-250 standard annotation with #Target({TYPE, FIELD, METHOD}))
Reference:
Autowiring Collaborators
Fine-tuning annotation-based
autowiring with qualifiers
Troubleshooting
If you don't know why there are two beans of the same type in the context, first of all navigate to the bean interface (I assume KeyCardManager is an interface, if not, do the same thing for the class anyway) and if you use Eclipse select Navigate > Open Type Hierarchy. If you find more than one concrete class that inherits from KeyCardManager (including KeyCardManager itself), then there's probably your problem.
If that is not the case, you probably have two beans of the same type in your application context. One way that can happen is when you define a bean through both XML and classpath scanning. I.e. if you have this line in your XML:
<context:component-scan base-package="org.example"/>
Make sure you don't manually wire any beans from the org.example package (or you will have double beans, which can lead to the problem you have).
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [fi.utu.keycard.business.KeyCardManager] is defined: expected single matching bean but found 2: [dataBaseTarget, database]
It seems you are autowiring by class type. but there are multiple bean available in the context with same class. which are dataBase & dataBaseTarget
byType
Allows a property to be autowired if
there is exactly one bean of the
property type in the container. If
there is more than one, a fatal
exception is thrown, and this
indicates that you may not use byType
autowiring for that bean. If there are
no matching beans, nothing happens;
the property is not set. If this is
not desirable, setting the
dependency-check="objects" attribute
value specifies that an error should
be thrown in this case.
Document

Categories