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
Related
The project I am working at the moment uses camel as the routing framework.
When configuring camel context in spring we pass a property file that contains a bunch of global properties needed when configuring camel routes or for controlling run time behavior:
<camel:camelContext xmlns="http://camel.apache.org/schema/spring" id="my-id">
<camel:propertyPlaceholder location="my-system.properties" id="global-properties"/>
...
</camel:camelContext>
and say my-system.properties has an entry like below:
my-system.properties
# Global properties that control my-system configuration and run time
...
foo={{bar}}
...
When configuring the routes I can access foo property using the {{foo}} notation. It is also available to other beans using #PropertyInject annotation. However there is one use case in my design when a plain POJO not created by spring (an enum instead but this is not relevant) needs to access my foo property. Because this POJO it is passed the CamelContext as a method argument I find it natural to think I should be able to get the value of foo from there. However I spent a bit of time and could not figure out by myself how.
I know I can load the properties file again or even get the system property System.getProperty("bar") and everything will work but it looks like cheating to me.
There is an api on CamelContext to resolve property placeholders - its the resolvePropertyPlaceholders method:
http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/CamelContext.html#resolvePropertyPlaceholders(java.lang.String)
If your POJO is not being managed by the SpringContext I don't see any way you can automatically inject the property. Although your approach may not seem the most fancy or elegant, it has the advantage of not giving you any overhead you could have by using another injection tool.
Is there a way to enforce the initialization of a Spring Bean in cases that the reference of the bean is never explicitly used or even requested in the ApplicationContext?
<bean class="foo.bar.FooBar>
<property name="fooBar" ref="foo.bar.reference"/>
</bean>
This bean is meant to do things inside, get's properties passed by IoC but it is never used by any other bean which implies that the it's reference is nowhere else configured.
My problem is, that this bean seems not to be initialized because of that.
I tried <bean .. lazy-init="false"/> but this did not do the trick.
How can ensure the bean is going to be initialized?
Since I cannot modify the application context, I would need a way doing it just in the XML configuration.
I'm not sure, but maybe you could try to use the singleton=true property for that bean - in non-singleton mode, the bean would be instatiated only if requested by the application.
http://docs.spring.io/spring/docs/1.2.9/reference/beans.html
(see 3.2.5)
Edit: Can you add some logging to ctor to see if it's called? If not, could you add an init-method and log something there?
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.
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
To be exact, how can I get the value of the <display-name> tag under the <web-app> tag stored in an application's web.xml in a Spring application context configuration XML file.
Ideally I would like something like the following...
<bean><property value="${servletContext.servletContextName}/></bean>
It seem like ServletContext.getServletContextName() does what I want but I can't seem to figure out how to get a handle on that in the Spring application context file.
Ok, the answer is trivial in Spring 3.0.x. Per the documentation for ServletContextFactory
Deprecated. as of Spring 3.0, since "servletContext" is now available as a default bean in every WebApplicationContext
So I decided to try the following and it worked!
<bean><property value="#{servletContext.servletContextName}/></bean>
Since servletContext object is implicitly defined we can access it via Spring EL using the #{} syntax.
I don't think you can do this via the XML config.
You can autowire a bean to receive the ServletContext object (or implement ServletContextAware), and fetch it from that programmatically, but I don't think the XML expressions have any visibility of it.
Maybe try the Expression Language?
<bean>
<property value="#{T(javax.servlet.ServletContext).getServletContextName()}"/>
</bean>
I suspect that would print null if it works though, since there is no context yet.