I've seen very few examples that uses this and was trying to get it to work but unable to:
package com.acme.service;
public class SampleServiceTest {
#Value("classpath:data.json")
private Resource jsonData;
#Test
public void testThis() {
String json = String.join("\n", Files.readLines(jsonData.getFile(), Charset.defaultCharset()));
}
}
Where my file structure (follows Maven standard) is as follows:
data-microservice (top folder)
-src/test/java/com/acme/service/SampleServiceTest
-src/test/resources/data.json
I've tried several of these but doesn't seem to work:
classpath:data.json
classpath:/data.json
classpath:src/test/resources/data.json
classpath:/src/test/resources/data.json
Looking to get help on this please, and if you could also provide a background on correct path (i.e. why that correct path works).
Found it, I was being silly and running test without any Spring context. It was a matter of just putting in these annotations on the test class:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
public SampleServiceTest {
//body here
}
And the "classpath:data.json" works!
Although if someone can explain why the classpath works without specifying the directories (src/test/resources) works, that would really be helpful.
Related
The structure of my project like the following:
I am sure everything okay but only one thing make the problem is #Autowired in StoredProcedureSpringDataJpaApplication.java like the following:
public class StoredProcedureSpringDataJpaApplication implements CommandLineRunner {
#Autowired
private StudentRepository stu;
public static void main(String[] args) {
SpringApplication.run(StoredProcedureSpringDataJpaApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
List<Student> students = stu.findAll();
students.forEach(System.out :: println);
}
}
Error description is:
Field stu in com.example.demo.StoredProcedureSpringDataJpaApplication required a bean of type 'com.repository.StudentRepository' that could not be found.
I know this is familiar question ,I did so many way to try to solve this problem in the internet even in stackoverflow but all can not solve my problem.
Help me solve this problem.
Use #ComponentScan({"com.example.demo", "com.repository"})
By default without this annotation it considers only annotations that exist inside the package where your #SpringBootApplication is declared, aka com.example.demo
Also together with the #ComponentScan use the following
#EnableJpaRepositories(basePackages = {"com.repository"})
Your package structure is incorrect StoredProcedureSpringDataJpaApplication.java should be in the root package. Another way is component scan placing annotation over StoredProcedureSpringDataJpaApplication.java. In your case, it should be like
This won't work for the repository class and as you have a different package structure so #EnableJpaRepositories(basePackages = "com.repository") will help you resolve this issue.
This happens because #SpringBootApplication does only scan in the package where it is defined.
Make sure it is placed at the root of your project and everything that should be scanned below it. For example:
com
- example
- demo
- StoredProcedureSpringDataJpaApplication.java
- repository
- StudentRepository.java
I have the following settings in my spring-boot project
application.properties:
file_path=${lookup_path}
lookup-file.file_1=${file_path}/file1.lku
lookup-file.file_2=${file_path}/file2.lku
and a corresponding config class LookupFileConfiguration, and also handler class to use this configuration:
#Component
#ConfigurationProperties("lookup-file")
public class LookupFileConfiguration {
private String file_1;
private String file_2;
// getter and setter methods skipped here
}
#Component
public class MyHandler {
#Autowired
private LookupFileConfiguration files;
}
I tried to run from command line:
mvn test -Drun.arguments=--lookup_path=C:\\my-proj\target\test-classes\lookupFiles\\
But it is not working. lookup_path seems not be used in the application.properties.
If I hard-code in application.properties file
file_path=C:\\my-proj\target\test-classes\lookupFiles\\
it is working fine.
I know I can use profiles for different environments. However, my project will run test cases in Bamboo plan. So I can only use bamboo variable ${bamboo_build_working_directory} but cannot predict the directory for test. Please help with a proper solution/suggestion for such case.
first: I'm really new to spring-boot and maven. So I still don't get how everything plugs together.
What I'm trying to achieve is some kind of plugin-feature for my application. From my research it seems the best way to do this is using ServiceLoader or the spring-boot implmentation of the SpringFactoriesLoader.
According to several instructions from the web I put two projects together
James (the main application) GitHub
TemperatureSensor (the plugin) GitHub
The JamesApplication provides an interfaces which is supposed to be implemented (de.maxrakete.james.device.domain.DeviceInterface).
The TemperatureSensor implements said class and exposes this in several ways.
For the ServiceLoader in in the file META-INF\services\de.maxrakete.james.device.domain.DeviceInterface with this content
de.maxrakete.james.plugin.TemperatureSensor.TemperatureSensor
For the SpringFactoriesLoader in the file META-INF\spring.factories with this content
de.maxrakete.james.device.domain.DeviceInterface=de.maxrakete.james.plugin.TemperatureSensor.TemperatureSensor
According to this page I tried two different implementations (see in the onApplicationEvent-function) in the MainApplication:
#SpringBootApplication
public class JamesApplication implements ApplicationListener<ApplicationReadyEvent> {
public static void main(String[] args) {
SpringApplication.run(JamesApplication.class, args);
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url: urls){
System.out.println("Classpath file: " + url.getFile());
}
}
#Override
public void onApplicationEvent(ApplicationReadyEvent event) {
ServiceLoader<DeviceInterface> loader = ServiceLoader.load(DeviceInterface.class);
loader.iterator();
List<DeviceInterface> foos = SpringFactoriesLoader.loadFactories(DeviceInterface.class, null);
}
}
I'm trying both ways to load the jar, but nothing is happening (I'm supposed to get some log-messages from the plugin) but this is not happening.
The way I'm running the application is like this:
java -cp "./plugins/TemperatureSensor-0.0.1-SNAPSHOT.jar" -jar james.war
As you see I'm trying to add the jar in the subfolder to the classpath, but in the ouput of the main-function (where I try to print all the files in the classpath) I only get Classpath file: /home/max/folder/james.war
Conclusion
So, there are three possible error-sources
Wrong cli command to add classpath files
Wrong declaration of interfaces in the META-INF folder
Wrong implementation of the Loader
Maybe I'm compiling the sources the wrong way?
Wrong configuration of the pom.xml
I really have no idea what the problem might be. I tried to provide you with as much information as possible and all the steps of my research. I hope someone finds some helpful clues, which I might have overlooked.
Thanks veryone!
I know a way to print the classpath of a project at runtime like here:
http://www.mkyong.com/java/how-to-print-out-the-current-project-classpath/
But sometimes the main is even too late, for example when using spring.
Is there a way to print something(e.g. classpath) even before Spring starts the injection process?
Providing some context, i am running a unit test in spring as follows:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "classpath:/jmsAppContext.xml")
public class TestProjectProvisioningIntegration
{
....
}
It finds correctly the jmsAppContext.xml, but fails to find one of the properties files.
To get the same effect as you have in the link you posted, you could get the classpath in a static initializer (just do the same as the example, only then in a static { ... } block instead of a main method. The JVM will execute the static initializer first, before loading any other classes your class depends on (other than the classes you reference in the static initializer).
I am trying to get gwt-test-utils to work. I set up the project in the following way:
src/main/java : all the java source code
src/test/java : the test source code
src/test/resources : resource files for the tests
I am building my project with gradle and eclipse. Gradle uses these directories correctly by default and I added all three of them as source directories to Eclipse.
I have successfully built and run the project and was able to execute some plain old JUnit tests as well as a GWTTestCase, so I think I set up the project and its dependencies correctly.
Now I wanted to use gwt-test-utils for some more advanced integration tests. To do so I did the following:
Add the gwt-test-utils and gwt-test-utils-csv to my dependencies
gwtTestUtilsVersion = '0.45'
testCompile group:'com.googlecode.gwt-test-utils', name:'gwt-test-utils', version:gwtTestUtilsVersion
testCompile group:'com.googlecode.gwt-test-utils', name:'gwt-test-utils-csv', version:gwtTestUtilsVersion
Add a gwt-test-utils.properties file to the directory src/test/resources/META-INF with the following content:
path/to/my/module = gwt-module
Added a class that extends GwtCsvTest to a package in the src/test/java directory. It is modeled after the second example in HowToWriteCsvScenario from the gwt-test-utils project wiki, replacing occurrence of their example classes with mine. It looks like this
#CsvDirectory(value = "gwtTests")
public class LoginLogoutTest extends GwtCsvTest
{
#Mock
private MainServiceAsync mainService;
private AppController appController = new AppController();
#CsvMethod
public void initApp()
{
appController.onModuleLoad();
}
#Before
public void setup()
{
GwtFinder.registerNodeFinder("myApp", new NodeObjectFinder()
{
#Override
public Object find(Node node)
{
return csvRunner.getNodeValue(appController, node);
}
});
GwtFinder.registerNodeFinder("loginView", new NodeObjectFinder()
{
#Override
public Object find(Node node)
{
return csvRunner.getNodeValue(appController.getRootPresenter().getCurrentlyActiveSubPresenters().iterator().next().getView(), node);
}
});
addGwtCreateHandler(createRemoteServiceCreateHandler());
}
}
added a csv-file for configuring the test to src/test/resources/gwtTests with the following content
start
initApp
assertExist;/loginView/emailTextBox
I tried executing it via the Eclipse's Run As > JUnit Test and indirectly via gradle build (which executes all the test cases, not just this one). Both lead to the same error:
ERROR GwtTreeLogger Unable to find type 'myPackage.client.AppController'
ERROR GwtTreeLogger Hint: Check that the type name 'myPackage.client.AppController' is really what you meant
ERROR GwtTreeLogger Hint: Check that your classpath includes all required source roots
The AppController class is the entry-point configured in the module I configured in gwt-test-utils.properties, which makes me think that configuration works correctly and the rest of the setup (dependencies and all) work as well.
In an earlier version I used the same file as a subclass of GWTTestCase and created an AppController instance in the same way. That worked, so I'm pretty sure the class path is setup correctly to include it as well. I also tried changing it back to the previous version just now and it still works.
I have no clue why the class is not found. Is there anything gwt-test-utils does differently which means I need to specifically set the class path for it? Otherwise it should just work, since both gradle and eclipse know about all the relevant source folders and dependencies.