Using the #Value annotation, is there any way to check (other than if-statements) if spring failed to do the injection and defaulted to null? Say, for example, you're doing it for 10+ variables; it would be rather extensive to go through the chain of if-statements. My intention is to track which failed, and throw an exception listing them. If possible, I'd rather not use reflection but I wouldn't mind if it was cleaner than a chain of if-statements.
UPDATE
Here's an example:
#Value("${my.package.username:#{null}}")
private String username;
When my.package.username isn't defined for Spring as my.package.username=someUserName in application.properties or as a JVM argument for Tomcat to pick it up in the form of
-Dmy.package.username=someUserName then it should default to null, which it does. Now, imagine there are 10+ of the above declaration for different variables, I would like to know how to determine which are null without checking each one. I was thinking there may be functionality in Spring to determine which failed since spring is doing the injection.
Spring treats "environment" as a normal property source, so it will not care too much from which property source came the final value.
In the example you gave you use null as fallback value, so you do a little opposite to what you would like to achieve.
But there are i think some tricks:
1) try to set some spring classes logging to DEBUG or even TRACE, maybe in logs it will be possible to find the information you want
2) if you want to know that within the program, then you really need to have distinction between the file property source and other, and do few ifs...
Related
Is it possible to insert a value stored in a configuration file (eg: application.properties) inside java annotation as follows :
#MyAnnotation(name="${application.prop1}")
and in application.properties I have:
application.prop1=foo
So that at runtime I have :
#MyAnnotation(name="foo")
Yeah, I don't think this is possible. Spring has no idea about your annotation and doesn't know what to do with it. Even if you try to use #Value(..) on top of your String name() default "" (inside of your annotation), Spring still won't make this happen as the annotation is not a bean. Trying to make your annotation a bean won't work either as far as I can tell. It sound like you are going to have to come up with some type of processor for this.
Perhaps looking into the following topics might help give you some ideas on how to put this together:
Auto Configuration: https://www.baeldung.com/spring-boot-custom-auto-configuration
SPeL: https://www.baeldung.com/spring-expression-language
Java Reflection: http://tutorials.jenkov.com/java-reflection/index.html
And of course, there's always the possibility that you might want to step back and consider why you want to do this? What are you trying to achieve that perhaps can be done a more "out of the box" way.
Yes, yse #Value annotation
#Value("property1")
There may be some related questions, but I think my situation is peculiar enough to justify a question on its own.
I'm working on a historically grown huge Java project (far over one million LOC, due to other reasons we're still bound to Java 6 at the moment), where reflection is used to display data in tables - reflection is not used for dynamically changing the displayed data, but just for using some kind of short cuts in the code. A simplified part of the code looks like this.
TableColumns taco = new TableColumns(Bean.class);
taco.add(new TableColumn("myFirstMember"));
taco.add(new TableColumn("mySecondMember"));
...
List<Bean> dataList = getDataFromDB(myFilterSettings);
taco.displayTable(dataList);
So the values of the table cells of each row are stored in an instance of Bean. The values for the first cell comes from calling itemOfDataList.getMyFirstMember() (so here comes the reflection part of the code). The rendering of the table cells is done depending on the return type of the itemOfDataList.getMyFirstMember().
This way, it's easy to add new columns to the table, getting them rendered in a standard way without caring about any details.
Problem of this approach: when the getter name changes, the compiler doesn't notice and there will be an exception at runtime in case Bean.getMyFirstMember() was renamed to Bean.getMyFirstMemberChanged().
While reflection is used to determine which getter is called, the needed info is in fact available at compile time, there are no variables used for the column info.
My goal: having a validator that will check at compile time whether the needed getter methods in the Bean class do exist.
Possible solultions:
modifying the code (using more specific infos, writing an adapter, using annotations or whatever that can be checked at compile time by the compiler), I explicitely don't want a solution of this kind, due to the huge code basis. I just need to guarantee that the reflection won't fail at runtime.
writing a custom validator: I guess this shouldn't be too complex, but I have no real idea how to start, we use eclipse as ide, so it should be possible to write such a custom validator - any hints for a good starting point?
The validator should show a warning in eclipse if the parameter in the TableColumn(parameter) isn't final (should be a literal or constant). The validator should show an error in eclipse if the TableColumn is added to TableColumns and the corresponding Bean.getParameter() doesn't exist.
as we use SonarQube for quality checking, we could also implement a custom rule checking if the methods do exist - not completely sure if such a custom rule is possible (probably yes)
maybe other solutions that will give a fast feedback within eclipse that some tables won't render correctly after some getter methods were renamed
What I'm asking for:
what will be easier in this situation: writing a custom validator for eclipse or writing a custom rule for SonarQube?
hints where to start either approach
hints for other solultions
Thanks for your help.
Some alternatives:
You could migrate to more modern Java for this pattern, it is a prime candidate for method references. Then, your IDE of choice can automatically take care of the problem when you refactor/rename. This can be done bit-by-bit as the opportunity/necessity arises.
You could write your own custom annotations:
Which you can probably get SonarQube to scan for
Which could allow you to take advantage of javax.validation.* goodies, so your code may look/feel more like 'standard' Java EE code.
Annotations can be covered by a processor during the build step, various build tools have ways to hook this up -- and the processor can do more advanced/costly introspection so you can push the validation to compile-time as opposed to run-time.
We have a spring application that runs in one of a few ways, depending on a specific property, which has to be one of a small set of values. When the application starts up, this property gets passed to a factory, which then builds slightly different bean implementations depending on it.
I'd like to write an integration test for the functionality this controls to ensure it works when the property is set to various values; so it needs to run one test with the property set to 1, one test with the property set to 2, etc. Each test needs to set the property as required, and then reload the configuration so that everything is reconfigured correctly.
Getting the context and manually refreshing it in each test seems simple enough, but how can I inject these different properties in the tests at runtime to control this? Is there any better way of organising this sort of configuration?
I am going to answer to your second question...so, is there any better way of organising this sort of configuration? It may be overwhelming for your case, but did you give a look to Spring Profiles? It does what you need and it is a new feature introduced in Spring 3.1, so it seems the way to go the Spring team chose for this kind of problems.
Here a great tutorial: http://blog.springsource.org/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/
I eventually found a way to actually do this directly. It's slightly messy, but not actually too bad.
Originally, the tests were being run with an #ContextConfiguration, and then later initialised with new TestContextManager(getClass()).prepareTestInstance(this); in the #Before (initialised separately so we could use runners other than the Spring one).
I extended this to first register a text execution listener which just grabbed the TestContext into the test itself whenever one became available:
contextManager.registerTestExecutionListeners(new AbstractTestExecutionListener() {
#Override
public void prepareTestInstance(TestContext freshTestContext) throws Exception {
testContext = freshTestContext;
}
});
The test itself then injects a property into a custom PropertyPlaceholderConfigurer (extremely simple: overrides resolvePlaceholder, calls super.resolvePlaceholder unless you've previously explicitly set the property) once it knows what the property's actual value is (not until the actual test, unfortunately), and calls:
testContext.markApplicationContextDirty();
contextManager.prepareTestInstance(this);
which makes the TestContext rebuild the application context, now using the newly changed property value.
Finally, you then need to remember to reset the property between tests, and probably mark the whole class as #DirtiesContext, to stop it interfering with your other tests.
Consider using a JVM System property that sets the environment (e.g. “my.env=sit”), telling the configurer which property file to use. For example:
<context:property-placeholder
location="classpath:db-${my.env}.properties"/>
If the “my.env” property was set to “sit”, then obviously the PropertyPlacementConfigurer would look for a file called “db-sit.properties".
Dont forget to set ignoreUnresolvablePlaceholders to true. Which will ensure that a configurer won’t fail if it can’t find a property.
I've written a state machine for navigating an automated telephone system, where each state is represented by its own Java class file, for a total of 50+ classes. Rather than write the instantiation and factory code myself, I decided to use Spring for bean definition and dependency injection. This works fine, however I have lost compile-time type checking by moving from:
State next = getState(Instructions.class);
to
ApplicationContext ctx = ...
State next = ctx.getBean("instructions", State.class);
Instead of having compiler checks that I've specified a real, existing state, I now have to rely on the id being spelled properly in both my source code and the bean xml.
Is there a better way to do this? I haven't worked extensively with Spring since early 2.0 days, so I don't have much real world experience to draw on. What are the drawbacks and advantages of this approach? Is there is something extra I could to to verify proper id strings are used?
Consider using Spring autowiring and in your class have:
class StateMachine
{
#Autowired
State next;
}
You can also use qualifiers to select amongst the different implementation you may have of State.
Turn off lazy initialization of Spring, and you'll at least cure the type safety department. You could also consider a 'grand central station' bean into which all of the states are inserted by name, this resulting in a yell if any go missing. You can still mispell in your Java code.
I would personally go about it one of two ways:
1) If only a few states needed access to a few other states, I would inject those directly (like Steve said in his answer):
#Inject
public setInstructions(Instructions instructions) { ... }
2) On the other hand, if any state needs access to any other one, no one wants to inject the other 49 states into each of the 50 classes, so I would have one central class that had all 50 injected and basically build my state machine in that class.
Spring really is a factory when it comes down to it, but tying yourself to the Spring API kind of goes against their philosophy, and as you mentioned, you lose type safety.
I'm at the point in my first real application where I am adding in the user settings. I'm using Java and being very OO (and trying to keep it that way) so here are my ideas:
Load everything in the main() and
pass it all 'down the line' to the
required objects (array)
Same as above, but just pass the
object that contains the data down
the line
Load each individual setting as
needed within the various classes.
I understand some of the basic pros and cons to each method (i.e. time vs. size) but I'm looking for some outside input as to what practices they've successfully used in the past.
Someone should stand up for the purported Java standard, the Preferences API... and it's most recent incarnation in JDK6. Edited to add, since the author seems to savvy XML, this is more appropriate than before. Thought I believe you can work XML juju with Properties too, should the spirit take you.
Related on SO: Preferences API vs. Apache solution, Is a master preferences class a good idea?
(well, that's about all the standing up I'm willing to do.)
Use a SettingsManager class or something similar that is used to abstract getting all settings data. At each point in the code where you need a setting you query the SettingsManager class - something like:
int timeout = SettingsManager.GetSetting("TimeoutSetting");
You then delegate all of the logic for how settings are fetched to this single manager class, whose implementation you can change / optimize as needed. For instance, you could implement the SettingsManager to fetch settings from a config file, or a database, or some other data store, periodically refresh the settings, handle caching of settings that are expensive to retrieve, etc. The code using the settings remains blissfully unaware of all of these implementaton decisions.
For maximum flexibility you can use an interface instead of an actual class, and have different setting managers implement the interface: you can swap them in and out as needed at some central point without having to change the underlying code at all.
In .NET there is a fairly rich set of existing configuration classes (in the System.Configuration) namespace that provide this sort of thing, and it works out quite well.
I'm not sure of the Java equivalent, but it's a good pattern.
Since configuration / settings are typically loaded once (at startup; or maybe a few times during the program's runtime. In any way, we're not talking about a very frequent / time-consuming process), I would prefer simplicity over efficiency.
That rules out option number (3). Configuration-loading will be scattered all over the place.
I'm not entirely sure what the difference is between (1) and (2) in your list. Does (1) mean "passing discreet parameters" and (2) mean "passing an object containing the entire configuration"? If so, I'd prefer (2) over (1).
The rule of thumb here is that you should keep things simple and concentrated. The advantage of reading configuration in one place is that it gives you better control in case the source of the configuration changes at some point.
Here is a tutorial on the Properties class. From the Javadocs (Properties):
The Properties class represents a
persistent set of properties. The
Properties can be saved to a stream or
loaded from a stream. Each key and its
corresponding value in the property
list is a string.
A property list can contain another
property list as its "defaults"; this
second property list is searched if
the property key is not found in the
original property list.
The tutorial gives the following example instantiation for a typical usage:
. . .
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();
// create application properties with default
Properties applicationProps = new Properties(defaultProps);
// now load properties from last invocation
in = new FileInputStream("appProperties");
applicationProps.load(in);
in.close();
. . .
You could, of course, also roll your own system fairly directly using a file-based store and an XML or YAML parser. Good luck!
We have recently started using JSR-330 dependency injection (using Guice from SVN) and found that it was possible to read in a Properties file (or any other map) and bind it inside Guice in the module in the startup code so that the
#Inject #Named("key") String value
string was injected with the value corresponding to the key when that particular code was called. This is the most elegant way I have ever seen for solving this problem!
You do not have to haul configuration objects around your code or sprinkle all kinds of magic method calls in each and every corner of the code to get the values - you just mention to Guice you need it, and it is there.
Note: I've had a look at Guice, Weld (Seam-based) and Spring which all provide injection, because we want JSR-330 in our own code, and I like Guice the best currently. I think the reason is because Guice is the clearest in its bindings as opposed to the under-the-hood magic happening with Weld.