We have a java project which is not on spring boot.
Its a normal spring project (spring version 4.1.4) and we have a lot of values defined under the spring bean annotated function, using the #Value annotation.
I am required to override those properties using a property file without having to tinker with the java class. Could you please help me understand, how can I achieve that?
I understand in Spring Boot projects we can do that using "spring.config.location" cmd argument but that will not work here I assume?
Related
I made a java library that has component and configuration classes.
When I use the library in other spring boot services, the beans are not registered because the component and configuration classes are not in the classpath.
I know we can use #ComponentScan but I don't want to change the service's code.
Is there a way of adding the classes to the classpath using application.properties?
Or is there anything I can do in the library so that the beans get registered?
If you are using Spring Boot, you can take advantage of Spring Autoconfiguration.
For that, you need to place a file spring.factories in META-INF/spring.factoriesin your library's .jar file. If you are using Gradle or Maven as a build tool and the standard folder structure, the file path is src/main/resources/META-INF/spring.factories.
Here's an example from a library I wrote:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.requirementsascode.spring.behavior.web.BehaviorConfiguration,\
org.requirementsascode.spring.behavior.web.SerializationConfiguration,\
org.requirementsascode.spring.behavior.web.BehaviorController
As you can see, after the first, Spring specific line, you list all of your configuration classes.
You can learn more about autoconfiguration here, for example.
You can do this using the autowireBean() method of AutowireCapableBeanFactory.
Read more here: AutowireCapableBeanFactory
I created a Spring Boot Java library which has a set of utilities that perform certain functions. This library can then be used across multiple applications that require its utilities. This library was designed as a Spring Boot application to allow these utilities to be injected in the application context.
Now I wish to execute a JUnit test on one of the utilities to ensure it is working correctly. However, since this application is basically a collection of utilities and not a stand-alone application, it does not have a main class or the main method annotated with #SpringBootApplication. Now, when I run the JUnit test, it comes up with an error.
java.lang.IllegalStateException: Unable to find a #SpringBootConfiguration, you need to use #ContextConfiguration or #SpringBootTest(classes=...)
Is it possible to test this Java library, or should we write the test cases only in the application that will be using this library?
I think there is some contradiction in what you say:
Created a Library...that was designed as a Spring Boot Application.
Library can be used across multiple applications that require its utilities.
If you implement "1" then there is a module with spring boot maven/gradle plugin configured to create a JAR of the application which is a library.
But if you have, say, module X that wishes to use your library, its impossible to add the dependency on your library in this module, spring boot JAR artifacts are not JARs in a Java Sense... So this won't work in both IDE and maven (I mean technically you'll have compilation errors).
Then you write something that completely makes sense: You say that the library by itself doesn't have a main class/#SpringBootApplication annotated class. From this I conclude that its not a spring boot application, but rather a spring boot starter module.
In this case you should not use #SpringBootTest annotation since it mimics the way of starting up the spring boot application (finds main class, scans the packages according to the package structure, loads the configurations and so forth). You don't need all this. Well, maybe technically you can still create a main class annotated with #SpringBootApplication and put it into src/test/java/.../ in a relevant package, but it doesn't really makes sense.
So basically you have two choices:
You can test the utilities without spring at all as if the utility is just a Java class, mock the dependency with Mockito and you're good to go. Since these tests are fast, it you be the best option.
You can run the integartion test by means of loading the spring context with all the required beans created by the application.
#ExtendWith(SpringExtension.class)
#ContextConfiguration(classes = {MyLibraryConfiguration.class})
public class SampleLibraryTest {
#Autowired
private SomeBeanFromTheLibrary theBean;
#Test
public void testFoo() {
....
}
}
Now although you can use component scanning (in this case you'll need slightly different annotations), in the example I've assumed that you're using java config, register all the beans of the library there and create a spring.factories that uses this Java Configuration file to create an autoconfiguration (you add a dependency on the library in module X and it loads the beans defined in the library automatically).
This #ExtendsWith (#RunWith for junit 4) has nothing to do with Spring Boot, it behaves as a "plain" spring, you can autowire beans, create mock beans, there is caching of configurations, etc.
I have a working Spring(MVC) project which I want to integrate with a simple java project (intended as daemon process).
I have added the Spring project to the simple Java Project in Eclipse but I am unable to invoke the Spring behavior for the service I want to use from the Spring-Hibernate project in the simple java project. All in am getting is a NullPointerException for the #Autowired entity in the Spring project. The Spring MVC project is already up and running while I am trying to run the daemon java program.
Though I am able to run the daemon process if I copy all the required service classes from the Spring project to the java project along with adding the required Spring jars (Basically making the original simple java as a Spring project now), I want to know how can Spring services be expoited by another simple java program.
You didn't state what spring version you are using. I assume it could be Spring3, but there should not be much differences in other versions ( > 2.5 ).
According to the Spring Framework Reference Manual (Chapter The IoC container) : Several implementations of the ApplicationContext interface are supplied out-of-the-box with Spring. In standalone applications it is common to create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext
A little further in same chapter :
Instantiating a Spring IoC container is straightforward. The location path or paths supplied to an ApplicationContext constructor are actually resource strings that allow the container to load configuration metadata from a variety of external resources such as the local file system, from the Java CLASSPATH, and so on.
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
The javadoc of ClassPathXmlApplicationContext says that this constructor (specifying context locations Create a new ClassPathXmlApplicationContext, loading the definitions from the given XML file(s) and automatically refreshing the context.
I currently use that kind of standalone initialization in tests.
I am trying to create a java email batch program that sends an email with an attachment each day to a specific email address, and I have to use Spring as the framework for this program. It is not going to be a web application, but since I'm implementing Spring into this, how would I go about this? I am totally new to Spring (and Java for that matter), but am unsure of which direction I need to go. Which jar files do I need? Spring Batch or Spring Framework? Also, where can I download the jar files for Spring Framework? The spring.io site won't let me download those jar files.
I very strongly suggest you use a build tool that handles dependency management. Such tools are Ant+Ivy, Maven and Gradle. They will take care of downloading the appropriate jars based on your declaration of what dependencies you need and will take care of all the transitive dependencies.
One good way of getting started with Spring Batch is to follow this tutorial using either Maven or Gradle (the latter would probably be easier since you don't need to install it - the tutorial's code has a wrapper).
The tutorial uses Spring Boot which vastly simplifies Spring configuration (which is a serious benefit especially for someone who is new to Spring)
As others already told you, I personally would not start any spring based project (means: any project) without maven! You have so much benefits from it, not only depencency management.
To start a spring app outside an application context:
#Configuration
public class AppConfig {
//any bean configurations here
}
//your entry class
static void main(String args[]) {
//get a reference to the spring context. use this context throughout your app!
ApplicationContext ctx = new AnnotationConfigApplicationContext(CacheConfig.class).get();
//optain any beans from the context. inside these beans, you can use any spring feature you like, eg #Autowired
ctx.getBean(YourBean.class).executeMethod();
}
I'd recommend starting with Spring Boot which will handle all of that for you. As others have mentioned, pick a build tool (Maven or Gradle) and follow the guide we provide on building a batch application here: http://spring.io/guides/gs/batch-processing/.
I'm using STS/GGTS 3.0.0 in eclipse, my spring project is a mix of java based, and xml based spring configuration.
I'd like to see some dependency diagrams of the spring beans, I can't figure out how to do that.
any ideas?
Kind Regards