When I published a war file for an application that works locally with Eclipse WTP, I had a FileNotFoundException for the bean.xml file with my beans definitions.
SEVERE: Exception sending context initialized event to listener instance of
class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanDefinitionStoreException:
IOException parsing XML document from class path resource
[META-INF/spring/beans.xml]; nested exception is java.
io.FileNotFoundException: class path resource [META-INF/spring/beans.xml]
cannot be opened because it does not exist
at Caused by: java.io.FileNotFoundException: class path resource
[META-INF/spring/beans.xml] cannot be opened because it does not exist
...
I created the war file with mvn war:war and copied in the webapps folder of Tomcat 7.
beans.xml is located in src/main/resources/META-INF/spring/beans.xml and I've the following in my pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/resources</directory>
</resource>
</webResources>
</configuration>
</plugin>
In the war file beans.xml gets packaged in META-INF/spring/beans.xml
In my web.xml I've:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/spring/beans.xml</param-value>
</context-param>
However the file is not found. How to solve the problem?
UPDATE: as Matthew Farwell suggested, is bean.xml is not packaged in the right location, so it's not in the class path, I think it's specified with maven-war-plugin parameters, now I try to look at its documentation. If someone knows it would be helpful.
UPDATE 2: As explained in maven-war-plugin documentation, there is an optional parameter called targetPath. I tried and after changing maven-war-plugin configuration adding targetPath it gets packaged correctly.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF/classes</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
UPDATE 3: About Ryan Stewart's suggestion, I started my initial pom setup using roo, but after that I've done many changes and I'm not using roo any more. The directory src/main/resources is not mentioned in any other places in pom.xml (I've used grep), however the only setting that looks suspicious to me is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration><encoding>UTF-8</encoding></configuration>
</plugin>
I've commented out that plugin, but nothing changed, then I commented out the configuration part of maven-war-plugin, but src/main/resources was not added to the war anymore, so for now I've added it back and I'm uploading it to test it online (it's still a staging server actually, not the final one anyway).
UPDATE 4 Ryan Stewart suggested that the problem was that I was running "mvn war:war" instead of "mvn package", and that was indeed the problem. With my targetPath, the resources appeared in WEB-INF/classes, but there weren't any classes there.
I was fighting an uphill battle, while instead the simpler solution was to remove the configuration part as in update 3, and use "mvn package" to build the war file. Thank you to both of you Ryan and Matthew, not only I solved my problem, but I've also learnt something more about Maven.
I have to assume you have another part of the POM that's excluding the file in question from being processed as a classpath resource, else it should be working. Either
Stop doing that, and it'll work fine--the content of src/main/resources becomes classpath resources by default--or
remove the classpath: from your path. Without that prefix, the path given in contextConfigLocation will be resolved against the root of the WAR file, and it will correctly find your file in META-INF/spring.
If you take path 1, then you should remove the webResources section, or you'll end up with the file in two places--not problematic, but potentially confusing.
In a war, / is not part of the classpath for a webapp. The classpath includes /WEB-INF/classes and all of the jars in /lib. See Apache Tomcat 6.0 - Class Loader HOW-TO
WebappX — A class loader is created for each web application that is
deployed in a single Tomcat instance. All unpacked classes and
resources in the /WEB-INF/classes directory of your web application,
plus classes and resources in JAR files under the /WEB-INF/lib
directory of your web application, are made visible to this web
application, but not to other ones.
The other web servers will have similar rules. If you wish to reference something as part of the classpath, put it in WEB-INF/classes.
Related
I have been looking over the maven war plugin and how to configure it. Here is my situation. I have a web application that is distributed to several production facilities. There are two files, in this web app, that are customized for each facility. These are /js/config.js and /META-INF/context.xml.
I have my project in a typical maven structure:
/src
|--/main
|--webapp
|--/js
|--config.js
|--properties
|--plant.properties
|--/META-INF
|--context.xml
I've left out non-essential directories for brevity.
The config.js has been altered to contain "parameter" I want substituted:
var Config {
...
system_title: '${plant_name} - Audit System',
...
}
The relevant portion of my pom is:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<filters>
src/main/webapp/js/properties/fayetteville.properties
</filters>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<directory>src/main/webapp/js</directory>
<filtering>true</filtering>
<exclude>**/properties</exclude>
</resource>
</webResources>
</configuration>
</plugin>
When I run "mvn clean package", I would expect to see ${plant_name} replaced with what is in my properties file. In this case, my properties file contains a single key-value pair:
plant_name=Austin
But I am not seeing the substitution. The resulting config.js in the target folder still contains ${plant_name} as does the config.js in the resulting war file.
I really don't want to use profiles if possible. Eventually, I want the build process to use a list of properties files to do this for all plants.
From my research, including a number of SO questions and answers, I feel I have things configured correctly.
What might I be doing wrong?
There seem to be many many posts about similar questions however I have been unable to find exactly what I am looking for.
Basically, I have a Java Application built using Maven in Eclipse. When I execute the project from withing Eclipse it works correctly as it can find all files in my resources directory. When I do a normal jar with dependencies build using maven it also works. However, in the final item I cannot get this to work:
I would like the resources to be excluded from the main executable jar and placed into a directory on the same level as the jar itself. This was a user can just make changes to the settings and execute the jar, so:
|--root level
|-Jar
|-resources
|-log4j.properties
|-settings.properties
I have the maven-jar-plugin doing this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<index>true</index>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.org.interfaces.SharepointClient.App</mainClass>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>http://org.com</url>
<key>value</key>
<Class-Path>resources/settings.properties resources/log4j.properties</Class-Path>
</manifestEntries>
</archive>
<excludes>
<exclude>settings.properties</exclude>
<exclude>log4j.properties</exclude>
</excludes>
</configuration>
</plugin>
And I have the maven-assembly-plugin creating the resources directory with all the resource files.
The project compiles and generates the directory structure as I want it however, the class files are unable to locate anything in the resources directory even though I specifically added them the classpath in the manifest.mf
This is the Manifest for details:
Manifest-Version: 1.0
Build-Jdk: 1.7.0_17
Class-Path: resources/settings.properties resources/log4j.properties
lib/log4j-1.2.17.jar lib/jaxws-api-2.2.11.jar lib/jaxb-api-2.2.9.ja
r lib/javax.xml.soap-api-1.3.5.jar lib/javax.annotation-api-1.2-b03
.jar lib/jsr181-api-1.0-MR1.jar lib/saxon-9.1.0.8.jar lib/saxon-9.1
.0.8-dom.jar
Created-By: Apache Maven 3.0.5
Main-Class: com.org.interfaces.SharepointClient.App
key: value
url: http://org.com
mode: development
Archiver-Version: Plexus Archiver
When Executed I receive an error on this line of code:
PropertyLoader.class.getClassLoader().getResourceAsStream("settings.properties");
The error is:
Exception in thread "main" java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Unknown Source)
at java.util.Properties.load0(Unknown Source)
at java.util.Properties.load(Unknown Source)
at com.org.interfaces.SharepointClient.PropertyLoader.getProps(PropertyLoader.java:29)
EDIT:
I am only having trouble getting java to load resources, not dependencies. Those appear to load correctly.
I think you are making this more difficult that it need be. Take a look at this http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html. You should simply add all of your dependencies to the pom.xml file. This way, whenever you transport your code, maven will use the pom.xml file to rebuild the project with all of your dependencies. http://mvnrepository.com/ makes it even easier. All you have to do is search for the dependency in the repository, and copy it into your pom file.
I'm using Intellij 13, and I've marked a directory as a resources directory (thinking that this would make all sub-files/folders available on the classpath), however when I run the project, an exception is thrown saying that a file called database.properties (inside the resources folder) can't be found at runtime.
Any ideas?
'database' folder is the folder marked as a resources folder.
I do not know intellij-idea, but I know that maven can deal with multiple resources directory provided they are declared in pom.xml. From Maven doc on Mave Resources plugin - Specifying resources directories :
...
<resources>
<resource>
<directory>resource1</directory>
</resource>
<resource>
<directory>resource2</directory>
</resource>
<resource>
<directory>resource3</directory>
</resource>
</resources>
...
If IntelliJ-IDEA has not declared your database directory such way in the pom, maven has no chance to find it.
Actually, I've created two files (MessageBundle_fr_BE and MessageBundle_us_US) where I put the different text to translate to internationalize my application
My problem is when I launch the application, I've following error :
Problem accessing /MyServlet. Reason:
Can't find bundle for base name MessageBundle, locale fr_FR
Caused by:
java.util.MissingResourceException: Can't find bundle for base name MessageBundle, locale fr_FR
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:796)
at com.application.myGoogleAppEngine.Internationale.<init>(Internationale.java:13)
at com.application.myGoogleAppEngine.Internationale.getInstance(Internationale.java:18)
at com.application.myGoogleAppEngine.MyServlet.doPost(MyServlet.java:52)
at com.application.myGoogleAppEngine.MyServlet.doGet(MyServlet.java:30)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
The project structure is below :
- src
- main
- webapp
- images
- js
- stylesheets
- resources
MessageBundle_fr_FR.properties
MessageBundle_us_US.properties
- WEB-INF
- appengine-web.xml
- logging.properties
- web.xml
- index.jsp
- java
- com.application.myGoogleApp
- test
- target
- pom.xml
- nbActions.xml
- README.md
And a part of my pom.xml to include 'src/main/webapp/resources' directory:
<configuration>
<archiveClasses>true</archiveClasses>
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
<resource>
<directory>${basedir}/src/main/webapp/resources</directory>
</resource>
</webResources>
</configuration>
Can you help me ?
Thank you
ResourceBundle.getBundle will only look in the classpath. It has no knowledge of .war files or servlets. You must place the .properties files in WEB-INF/classes.
I can see that you are using maven archetypes. So, I suggest to have template below:
src/main/java
src/main/resources
-MessageBundle_fr_FR.properties
-MessageBundle_us_US.properties
src/main/webapp
You must create src/main/resources and move your properties to this folder.
I have a situation where I have a web application that is built using maven (i.e., maven-war-plugin). For each code modification, we have had to manually launch maven and restart the application server. Now, to reduce build cycle overhead, I want to use WTP to publish the webapp.
Now, we have resource processing with Maven, and there are some additional Maven tasks defined in our POM when building the webapp. Therefore m2eclipse seems like a natural solution.
I have gotten far enough that the Maven builder is running these tasks and filtering resources correctly. However, when I choose "Run on Server", the WAR file does not look like it would if I built it in Maven.
I am guessing that this is because WTP actually builds the WAR, and not the m2eclipse builder. So even though we have configured the maven-war-plugin in our POM, those settings are not used.
Below is a snippet with our maven-war-plugin configuration. What is configured under "webResources" is not picked up, it appears:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1-alpha-2</version>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<workDirectory>${project.build.directory}/work</workDirectory>
<webappDirectory>${project.build.webappDirectory}</webappDirectory>
<cacheFile>${project.build.webappDirectory}/webapp-cache.xml</cacheFile>
<filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
<nonFilteredFileExtension>png</nonFilteredFileExtension>
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
<nonFilteredFileExtension>jsp</nonFilteredFileExtension>
</nonFilteredFileExtensions>
<webResources>
<!-- Add generated WSDL:s and XSD:s for the web service api. -->
<resource>
<directory>${project.build.directory}/jaxws/wsgen/wsdl</directory>
<targetPath>WEB-INF/wsdl</targetPath>
<filtering>false</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</webResources>
</configuration>
Do I need to reconfigure these resources to be handled elsewhere, or is there a better solution?
To fill in an answer to my own question if someone else comes across the same problem, I ended up adding the following to my webapp project:
<resource>
<directory>${project.build.directory}/jaxws/wsgen/wsdl</directory>
<filtering>true</filtering>
<targetPath>${project.basedir}/src/main/webapp/WEB-INF/wsdl</targetPath>
<includes>
<include>**/*</include>
</includes>
</resource>
(inside the resources element under build).
It works fine since my WSDL files are generated in the generate-resources phase and places them in target/jaxws/wsgen/wsdl. Then those are moved into src/main/webapp/WEB-INF/wsdl, where the WTP builder picks them up when building the WAR file.
Note: I should mention that I get some problems with the eclipse plugin for Maven now (i.e., mvn eclipse:eclipse), because apparently you are not allowed to have absolute paths in targetPath. Not found a satisfactory workaround yet...
I'm not sure (filtered) web resources are supported yet, see MNGECLIPSE-1149. The issue has a patch (and a workaround) that could work for you. Also have a look at the hack from this thread.
WebResources are supported in m2e-wtp 0.12 and later versions (compatible with Eclipse Helios and Indigo).
For more details, see http://community.jboss.org/en/tools/blog/2011/05/03/m2eclipse-wtp-0120-new-noteworthy