We have an app that does not run in a web container so I am trying to start Spring up. In the "main" function we have this:
public static void main(String[] args) throws InterruptedException, IOException, AlreadyAliveException, InvalidTopologyException, AuthorizationException {
// starting up spring...
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:/applicationContext.xml");
DataSourceTransactionManager dstm = applicationContext.getBean("markiscool", DataSourceTransactionManager.class);
dstm.toString();
}
And my applicationContext.xml contains:
<bean id="markiscool" class="blah.entities.LocationEntity" />
The app, on startup, logs this:
[INFO] ClassPathXmlApplicationContext - Refreshing
org.springframework.context.support.ClassPathXmlApplicationContext#295cd6e5:
startup date
[Thu Dec 17 10:28:28 CST 2015]; root of context hierarchy
Exception in thread "main"
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
bean named 'markiscool' is defined
I have tried putting garbage in the xml file but it doesn't fail so it must not be finding the file. Also, the file is on the classpath:
I have also stuck the file in about every place I can think of. It does not load. Help!
Try to use FileSystemXmlApplicationContext:
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("/conf/applicationContext.xml");
Instead of:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:/applicationContext.xml");
Try this:
Right click -> properties -> Deployment Assembly
Put an entry: conf -> /
try
new ClassPathXmlApplicationContext("applicationContext.xml");
1) Put applicationContext.xml into the config folder
2) Tell Maven to include applicationContext.xml in the jar it creates
3) Use the function ClassPathXmlApplicationContext to pull in the file
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:conf/applicationContext.xml");
Note: FileSystemXmlApplicationContext will not work if you are trying to access a file inside of a jar. For this reason I recommend using ClassPathXmlApplicationContext because it works whether you are running the project in eclipse or via the jar
Related
I'm searched a lot for a solution for my case, basically i will start/run my spring boot application in other spring boot application.
How i tried do:
String[] args = { "-Dspring.profiles.active=development",
"-Dspring.config.location=config/example-db-development.properties,config/example-custom-development.properties",
"-Dloader.path=test/lib" };
File fatJar = new File("D:/spring-boot-example/test/spring-boot-example-api.jar");
ClassLoader classLoader = new URLClassLoader(new URL[] { fatJar.toURI().toURL() });
Class<?> mainClass = classLoader.loadClass(getMainClassName(fatJar));
Method mainMethod = mainClass.getMethod("main", String[].class);
mainMethod.invoke(null, new Object[] { args });
private static String getMainClassName(File fatJar) throws IOException {
try (JarFile jarFile = new JarFile(fatJar)) {
return jarFile.getManifest().getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
}
}
This started the example project, however, I need to add some dependencies of the example project to the project that should start the same.
And I'm still having problems for springboot to be able to create beans, for example:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'vendaPDVControllerImpl' defined in URL [jar:file:/D:/dsv-git/dsv-java/pdv-prototipos/spring-boot-integrador-testes/test/spring-boot-integrador-api.jar!/BOOT-INF/classes!/br/com/sysmo/integrador/api/impl/VendaPDVControllerImpl.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [br.com.sysmo.integrador.api.impl.VendaPDVControllerImpl] from ClassLoader [org.springframework.boot.loader.LaunchedURLClassLoader#31f924f5]
I do not want to have to add dependencies of the sample project on the project that should start it, and I already looked in the stack overflow for solutions, but found none that solves my problem.
I'd like something like this, but from the classLoader, or another solution that makes it possible to start my application without adding its dependencies to my project:
java -jar -Dspring.profiles.active=development -Dspring.config.location=config/example-db-development.properties,config/example-custom-development.properties -Dloader.path=lib example-api-1.00.00.000.jar
I have a default package called com.voja.springtest and another one called com.voja.springtest.beans where I have an beans.xml file.
I can get it like so using FileSystemXmlApplicationContext :
ApplicationContext context = new FileSystemXmlApplicationContext("C:/Users/Voja/Desktop/_/vj/springtest/src/main/java/com/voja/springtest/beans/beans.xml");
But ClassPathXmlApplicationContext can't find it like so (and it should per the tutorial I am doing):
ApplicationContext context = new ClassPathXmlApplicationContext("com/voja/springtest/beans/beans.xml");
Why?
you use wrong parh , in your case it should be like :
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:beans.xml");
4.7.2.2 The classpath*: prefix
When constructing an XML-based application context, a location string
may use the special classpath*: prefix:
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml"); This
special prefix specifies that all classpath resources that match the
given name must be obtained (internally, this essentially happens via
a ClassLoader.getResources(...) call), and then merged to form the
final application context definition.
The Classpath*: portability classpath*: prefix
FileSystemXmlApplicationContext picks the XML file from absolute path by appending keyword "file" and also can fetch from classpath by appending keyword "classpath".
You can access the file as below
ApplicationContext context = new FileSystemXmlApplicationContext("classpath:spring-app.xml");
I am absolutely confused with application context in spring. If i use spring (simple spring) create a beans.xml and then invoke Application context from (for example) main() method.
ApplicationContext context = new FileSystemXmlApplicationContext
("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml");
all works well. But I don't understand if i move file on directory above or in another directory(for example) it will be ok?
in spring-mvc there is context for each DispatcherServlet which i create and where i specify some beans, there is common context for all servlets, how to specify this? in web.xml?
in general, please explain me this moment (I read spring in action, i undesrstand almost all, but these tricky moment isn't shown there.
From FileSystemXmlApplicationContext java doc:
Standalone XML application context, taking the context definition files from the file system or from URLs, interpreting plain paths as relative file system locations (e.g. "mydir/myfile.txt"). Useful for test harnesses as well as for standalone environments.
The key words here are context definition files, so you can pass paths to as many xml-files, as you want. Besides that, you can create an application context and pass it to the new one as a parent:
FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent)
Thus you can easily create the needed hierarchy of contexts.
ApplicationContext parentContext = new FileSystemXmlApplicationContext
("C:/some/path/ParentBeans.xml");
ApplicationContext childContext = new FileSystemXmlApplicationContext
(new String[]{"C:/some/path/ChildBeans1.xml", "C:/some/path/ChildBeans2.xml"}, parentContext);
if i move file on directory above all in another directory(for example) it will be ok?
As long as your path to file is correct and reachable - it's Ok.
I'm a total beginner in Spring Batch Framework, and I found easily understandable codes from http://www.javabeat.net/introduction-to-spring-batch/ to use as a learning tools. I have my project set up in Eclipse similiar to the codes from the page, it looks like this :
and the code executes the jobs in fileWritingJob.xml using CommandLineJobRunner like so :
package net.javabeat.articles.spring.batch.examples.filewriter;
import org.springframework.batch.core.launch.support.CommandLineJobRunner;
public class Main {
public static void main(String[] args) throws Exception {
CommandLineJobRunner.main(new String[]{"fileWritingJob.xml", "LayeredMultiThreadJobTest"});
}
}
and it runs as expected with no problem. But when I move the fileWritingJob.xml to another dir (still under the project dir) it doesn't run. I've tried changed the filename arguments at the CommandLineJobRunner method using relative and full path but it still doesn't run. For example, if create a directory under the project directory (same level as config) named jobs and put the xml there then pass the filepath to CommandLineJobRunner like this:
CommandLineJobRunner.main(new String[]{"/jobs/fileWritingJob.xml", "LayeredMultiThreadJobTest"});
or this
CommandLineJobRunner.main(new String[]{"../jobs/fileWritingJob.xml", "LayeredMultiThreadJobTest"});
it doesn't work.
But when I tried creating a subdir under the config directory and put the fileWritingJob.xml there, like this
CommandLineJobRunner.main(new String[]{"configsubdir/fileWritingJob.xml", "LayeredMultiThreadJobTest"});
it runs. It's as if the CommandLineJobRunner only checks the config directory.
I'm running out of ideas, can anyone help me?
UPDATE : After digging around a bit, thanks to Michael Minella's suggestion about ClassPathXmlApplicationContext I am able to put the xml wherever I want. I also consulted to this page Spring cannot find bean xml configuration file when it does exist and http://www.mkyong.com/spring-batch/spring-batch-hello-world-example/
So what I do now is declaring a new context by using ClassPathXmlApplicationContextand then run it using job launcher, here is how :
public static void main(String[] args) {
String[] springConfig =
{
"file:/path/to/xml/file"
};
ApplicationContext context = new ClassPathXmlApplicationContext(springConfig);
JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
Job job = (Job) context.getBean("JobName");
try {
JobExecution execution = jobLauncher.run(job, new JobParameters());
System.out.println("Exit Status : " + execution.getStatus());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Done");
}
Thank you very much for all your inputs!
A little detail around what is happening when you pass in the path to the xml based job definition to the CommandLineJobRunner. All we do is we pass that string to the constructor of ClassPathXmlApplicationContext. Because of that, it is expected that the xml file for the job definition be on the application's classpath. I can't tell from your project screen shot how you are building the project so I'm not sure if the config directory is on your classpath or not. However, if it is on the classpath and lives at the root of it, I'd expect you to be able to pass the path to the fileWritingJob.xml as "/config/fileWritingJob.xml".
The source for this class can be helpful when debugging this type of issue. You can find the source code for the CommandLineJobRunner here: https://github.com/spring-projects/spring-batch/blob/master/spring-batch-core/src/main/java/org/springframework/batch/core/launch/support/CommandLineJobRunner.java
You can specify the job path relative to your config directory. For example, if fileWritingJob.xml is in config/jobs/ directory, then in you can execute the job as follows:
CommandLineJobRunner.main(new String[]{"jobs/fileWritingJob.xml", "LayeredMultiThreadJobTest"});
Likewise, if the job configuration file is outside of the config directory, you can write:
CommandLineJobRunner.main(new String[]{"../fileWritingJob.xml", "LayeredMultiThreadJobTest"});
You can specify an absolute path for locating the job.
I am trying to create EJBContainer in order to do some integration testing. here is the code:
Map properties = new HashMap();
properties.put(EJBContainer.MODULES,
new File[]{new File("target/classes"),
new File("target/test-classes")});
ec = EJBContainer.createEJBContainer(properties);
ctx = ec.getContext();
It throws exception: javax.ejb.EJBException: Can't find directory D:\jboss-4.2.3.GA\jboss-4.2.3.GA\common\lib
Actually there is no common/lib directory in Jboss folder. When I debug the code inside of EJBContainer i see that the problem is in JBossStandaloneEJBContainerProvider class which seems the default container provider class. Is there a way to change this provider? Or maybe I am doing something incompatible?