Browse spring context - spring

Currently, I'm working on a project which has a large number of dependencies.
During development, I sometimes have issue with some spring bean.
Normally, the stack trace can tell me the name of the bean. However, it does not shows me which context.xml file declares the bean. Moreover, it does not tell me which .jar file contains the context file and how that context file is imported into my project (I means the chain of import).
As there are many depedencies, not all context file are uses, many beans are override....
It takes me a lot of time to search the correct context file. One simple solution is to import all related project into my eclipse workspace and everything becomes horribly slow.
I'm thinking about writing a tools to speed up the process:
Given a name of spring bean / the class of bean, the tool will search in the whole class path of application and returns:
The spring context file which declares the bean.
The .jar file that contains the spring context file.
Extract the content spring context file and show it directly to user
If user provides the root spring context file, the tool will shows the import chain to the destination spring context file.
It does not take lots of time to implement this but I just wonder whether somebody has already implement it? I just don't want to reinvent the wheel.
I found the project https://github.com/julior/spring-inspector. It's interesting, but it's not what I need.
If you know a tool like the one above, I'd be very happy to know about it.

You totally should look at Intellij IDEA's great support for Spring Framework.
More information available here: http://www.jetbrains.com/idea/features/spring_framework.html
To find interesting bean in xml config you just need to click on green bean image.
Intellij IDEA is definitely worth its price.

Related

SpringBoot creating a framework starter library

I am creating a library using spring-boot (v2.1.6.RELEASE) as a starter project that will facilitate as base extension jar responsible for configuring and starting up some of the components based on client project properties file.
The issue I am facing is that if the client project's SpringBoot Application class contains the same package path as library everything works like charm! but when client project contains different package path and includes ComponentScan, it is not able to load or start components from the library.
Did anyone encounter this issue? how to make client application to auto-configure some of the components from library jar?
Note: I am following the library creation example from here: https://www.baeldung.com/spring-boot-custom-starter
There are many things that can go wrong here, without seeing relevant parts of actual code its hard to tell something concrete. Out of my head, here are a couple of points for consideration that can hopefully lead to the solution:
Since we use starters in our applications (and sometimes people use explicit component scanning in there spring applications) and this obviously works, probably the issue is with the starter module itself. Don't think that the fact that the component scan is used alone prevents the starter from being loaded ;)
Make sure the starter is a: regular library and not packaged as a spring boot application (read you don't use spring boot plugin) and have <packaging>jar</packaging> in your pom.xml or whatever you use to build.
Make sure you have: src/main/resources/META-INF/spring.factories file
(case sensitive and everything)
Make sure that this spring.factories file indeed contains a valid reference on your configuration (java class annotated with #Configuration). If you use component scanning in the same package, it will find and load this configuration even without spring factories, in this case, its just kind of another portion of your code just packaged as a separate jar. So this looks especially "suspicious" to me.
Make sure that #Configuration doesn't have #Conditional-something - maybe this condition is not obeyed and the configuration doesn't start. For debugging purposes maybe you even should remove these #Conditional annotations just to ensure that the Configuration starts. You can also provide some logging inside the #Configuration class, like: "loading my cool library".

Best way to get Spring Bean info from context WIHOUT creating app context?

I have a Spring (3.1.) app that has a large app-context.xml file. There is a second very small stand-alone application that needs just a few parameters from one of the beans that are configured in that xml file.
Rather than that little application instantiating the whole application context (which builds a lot of connections, etc), I just want to read in the couple of configuration parameters that are contained in that file.
I could of course create a new smaller small-app-context.xml that only has the configuration i need or put those parameters in a properties file, but then I need to maintain that information in two places, which I am trying to avoid. I know I could read in and parse the raw XML file (not exactly sure the most efficient way to do that). However, I was hoping that Spring provides a nice way to do this but I haven't found it.
Does Spring provide a clean way to do this?
Thanks.
In Spring you can have multiple configuration files. So for the part that you would like to reuse you would create a smaller, self-contained config file. It can remain in the original project and your app-context.xml can include it. Then your new, small project could include the small config xml and you wouldn't need to maintain the information in two locations.
I could of course create a new smaller small-app-context.xml that only has the configuration i need or put those parameters in a properties file
I would agree that configuration belongs in a properties file. Not the application context file. You should not be maintaining the configuration in two places. You should have the configuration once in your properties file and then make that available to any contexts which require it.

File Set Not Configured For The File Intellij IDEA

When I open a Spring configuration files at my application on Intellij IDEA sometimes it says
File Set Not Configured For The File
and gives me a link
Configure File Set
When I click it it says:
MVC dispatcher servlet
Create New File Set
or opens a new window cnd let me check some files.
What happens when I click them and what is this for? I click MVC dispatcher Servlet and check the code but doesn't see any changes.
What it is for?
this is for IDEA to help you out with dependencies between different files.
For example you have "service-spring-config.xml" and "mvc-spring-config.xml", where the MVC config uses some beans from the Service config. If you add these both files to the "File Set", IDEA will know that these two files represent a single application context.
By knowing that, it will help you autocomplete beans in XML + will inform you if something is not resolvable without you having to actually run the app.
I click MVC dispatcher Servlet and check the code but don't see any changes
This is because you only have a single file (for now). Later on, you can add some other configs that use/reference beans from each other => then it'll become REALLY helpful
From IDEA File Sets documentation:
By combining Spring XML configuration files in a file set you tell IntelliJ IDEA that these files are mutually related. In this way you form a common editing context for these configuration files and get all the associated coding assistance.
Spring file sets on IntelliJ are for grouping related files.
IntelliJ could autodetect some of this groups, for example files that are loaded with ContextLoaderListener on web.xml or default files for DispatcherServlet (That seems to be your case)
When IntelliJ asks to configure a File Set for a Spring file, is 'cause IntelliJ couldn't detect a default way to include in a group, for example files that are loaded within the ApplicationContext's constructor Ex:
new ClasspathXmlApplicationContext("somefile.xml","anotherfile.xml");
When file sets are correctly configured IntelliJ could bring many goodies like auto-complete, navigation, validation, dependency graphs and others

Ibatis2 and test context

I'm having a stupid configuration issue with Ibatis in my Spring project. Please don't jump on me about how all this was setup, I'm just following the "in house project structure policy".
So here is the structure, we have the "src/main/resources/META-INF/" folder that contains all of our config files used by the application, and then there is a "src/test/resources/META-INF/" that contains only the config files that have different settings to run unit testing.
Well in our case that's only one file, the src/main/resources/META-INF/spring/application-config.xml became the src/test/resources/META-INF/spring/test-application-config.xml. I'm am not going to outline the small differences between the two, because that part works fine.
The test-application-config.xml imports the src/main/resources/META-INF/spring/data-access-config.xml file just fine, which in turns use the src/main/resources/META-INF/ibatis/sqlmap-config.xml successfully... After that is when it goes to Hell.
See up until now we're using Spring to find the next config files in the classpath, but when we hit sqlmap-config.xml we leave the spring framework for the ibatis framework I believe, which loads the resource files defined inside it relative to the classpath (that's taken from the doc, whatever that means).
Inside the sqlmap-config.xml are defined a few resource files we're using that live inside the src/main/resources/META-INF/ibatis/mapping folder.
They are referenced like this:
<sqlMapConfig><sqlMap resource="/META-INF/ibatis/mapping/MyObject.xml"/></sqlMapConfig>
That works fine when I run the app normally, but when I run my JUnit test cases I get an IO exception stating that it can't find the file /META-INF/ibatis/mapping/MyObject.xml.
I've tried to change the path in the sqlmap-config.xml to "mapping/MyObject.xml" but that didn't help. I've also tried to use the Spring classpath prefix "classpath:META-INF/ibatis/mapping/MyObject.xml", didn't work either.
Anyone would have any idea on how to set that Ibatis properly so it works for both the app and the junit?
Thanks.
To solve this problem, I removed all the the Ibatis files and folders from the src/test/resources/META-INF folder.
The sqlmap-config.xml in src/main/resources/META-INF/ibatis/mapping file now maps like this:
<sqlMapConfig><sqlMap resource="META-INF/ibatis/mapping/MyObject.xml"/></sqlMapConfig>
Please note that compared to my initial post the leading "/" is gone... I think that's what made the difference here.
Hopes this helps anyone running into similar issues.
Just to see whether what you are saying is actually the problem.. you might want to place your mappings (MyObject.xml) in the same folder as sqlmap-config.xml. I say this because I've had my fair share of spring + ibatis + unit testing problems. (see resolved question asked by me)
Also, you might be getting IO exception because the mappings file does not exist outside the container (when you run tests).
You should also post definition for bean created from SqlMapClientFactoryBean. This should have configLocation property that contains path to sqlMapConfig xml
I had the same problem and could not find a (quick) solution that explained what exactly could be going wrong. Hence my answer.
As Spring documentation for Ibatis says:
Remember that iBATIS loads resources from the class path, so be sure
to add the 'Account.xml' file to the class path.
In your case by adding META-INF to your webproject build path i.e. if you used Eclipse, set <classpathentry kind="src" path="META-INF"/> in your projects' .classpath (This will be visible under Navigator view in Eclipse)

Multiple messageSources in Spring configuration files

our web application uses Spring 2.5. It consists of several modules, each of which can bring additional Spring context files, which are loaded automatically (into one application context). We want to let each module provide additional resource bundles (for I18N support).
Spring supports internationalization by registering a bean with name messageSource in the configuration file, but this assumes I know exactly what is the fully qualified name of the class or properties file that contained the translates strings. This is a problem because other modules might have their own properties files put in a different location. So I'm looking for a way to let each module define its own messageSource with its own resource bundles and I don't know how to do it.
Does anybody know the solution to this problem?
Thanks.
I have used the Message Sources in Spring for some i18n support. In my case I only needed one so it was easy to inject the one message source I needed into the service bean that I was creating.
I was hoping to see something like what I will propose later on in the Spring sources itself. But I don't see anything that will aggregate heterogeneous message sources. If all of them will be parts of a resource bundle like property files, I'm sure you could write a wrapper for ResourceBundleMessageSource that could be dynamically updated as beans were registered.
However, if you wanted to aggregate heterogeneous MessageSources, this is what I would suggest. Create an message source aggregating bean that upon loading asks the ApplicationContext for beans of type MessageSource.class. This aggregating bean can then let each source attempt to resolve the key and format the message. Depending on how many files/msg source classes you have you may want to allow the aggregating implementation to prioritize which ones it attempts to use first. If performance becomes a problem, you could also cache which source resolved which keys so that the aggregator doesn't have to guess each time.

Resources