I'm using a library that has a dependency on JSF.
When I try to run my project, it show following exception massage..
java.util.MissingResourceException: Can't find bundle for base name /Bundle, locale en_US
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1427)
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1250)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:705)
Any ideas ?
The exception is telling that a Bundle_en_US.properties, or Bundle_en.properties, or at least Bundle.properties file is expected in the root of the classpath, but there is actually none.
Make sure that at least one of the mentioned files is present in the root of the classpath. Or, make sure that you provide the proper bundle name. For example, if the bundle files are actually been placed in the package com.example.i18n, then you need to pass com.example.i18n.Bundle as bundle name instead of Bundle.
In case you're using Eclipse "Dynamic Web Project", the classpath root is represented by src folder, there where all your Java packages are. In case you're using a Maven project, the classpath root for resource files is represented by src/main/resources folder.
See also:
Maven and JSF webapp structure, where exactly to put JSF resources
maven-tomcat-plugin
If you start the Project using the maven-tomcat-plugin / maven-tomcat7-plugin, you must place the Bundle.properties, or even the Resource.properties in src/main/webapp/WEB-INF/classes. Dont ask why, its because how the plugin fake a tomcat.
If you are running the .java file in Eclipse you need to add the resource path in the build path .
after that you will not see this error
In my case the problem was using the language tag "en_US" in Locale.forLanguageTag(..) instead of "en-US" - use a dash instead of underline!
Also use Locale.forLanguageTag("en-US") instead of new Locale("en_US") or new Locale("en_US") to define a language ("en") with a region ("US") - but new Locale("en") works.
I had the same problemo, and balus solution fixed it.
For the record:
WEB-INF\faces-config is
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<locale-config>
<default-locale>en</default-locale>
</locale-config>
<message-bundle>
Message
</message-bundle>
</application>
</faces-config>
And had Message.properties under WebContent\Resources (after mkyong's tutorial)
the pesky exception appeared even when i renamed the bundle to "Message_en_us" and "Message_en". Moving it to src\ worked.
Should someone post the missing piece to make bundles work under resources,it would be a beautiful thing.
In my case I was dealing with SpringBoot project and I got the same exception.
Solution is made by adding env.properties file into classpath (i.e. src/main/resource folder). What was making the issue is that in log4j configuration there was property like
<Property name="basePath">${bundle:env:log.file.path}</Property>
The Bundle.properties file must be in the directory of the .class files. If it is located in the src directory then you need to make sure to copy it to the bin (output) directory in the same package.
Bundle names have to be fully qualified, like if your bundle Bundle.properties
is inside x.y.z package, then you have to write ResourceBundle.getBundle("x.y.z.Bundle");
I had the same problem using Netbeans. I went to the project folder and copied the properties file. I think clicked "build" and then "classes." I added the properties file in that folder. That solved my problem.
I use Eclipse (without Maven) so I place the .properties file in src folder that also contains the java source code, in order to have the .properties file in the classes folder after building the project. It works fine.
Take a look at this post: https://www.mkyong.com/jsf2/cant-find-bundle-for-base-name-xxx-locale-en_us/
Hope this help you.
The problem must be that the resource-bunde > base-name attribute at the faces-config.xml file has a different path to your properties. This happened to me on the firstcup Java EE tutorial, I gave a different package name on then project creation and then Glassfish was unable to find the properties folder which is on "firstcup.web".
I hope it helps.
Make sure you didn't add the properties files in the wrong resources folder as there is one under 'Web Pages' and one under 'Other Sources/...'. They needed to be under 'Other Sources/...'.
I was able to resolve the issue, the resource was in my project directories but when the junit utility tries to load it, it was returning an error of MissingResourceException. And the reason was the resource was in the not on the classpath of the test class package so when I added the cfg/ folder to my classpath path entry in eclipse and set the output directory in the build conf to the same class package the issue was resolved.
When you try this approach just make sure, the classpath conf file shows the classpath entry of the resource directory (eg. cfg/)
In maven, folder resources, create the same package structure where the configuration files are located and copy them there
Related
I am trying to make my first bean in Spring but got a problem with loading a context.
I have a configuration XML file of the bean in src/main/resources.
I receive the following IOException:
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [src/main/resources/beans.xml]; nested exception is
java.io.FileNotFoundException: class path resource [src/main/resources/beans.xml] cannot
be opened because it does not exist
but I don't get it, since I do the following code test:
File f = new File("src/main/resources/beans.xml");
System.out.println("Exist test: " + f.exists());
which gives me true! resources is in the classpath. What's wrong?
Thanks, but that was not the solution. I found it out why it wasn't working for me.
Since I'd done a declaration:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
I thought I would refer to root directory of the project when beans.xml file was there.
Then I put the configuration file to src/main/resources and changed initialization to:
ApplicationContext context = new ClassPathXmlApplicationContext("src/main/resources/beans.xml");
it still was an IO Exception.
Then the file was left in src/main/resources/ but I changed declaration to:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
and it solved the problem - maybe it will be helpful for someone.
Edit:
Since I get many people thumbs up for the solution and had had first experience with Spring as student few years ago, I feel desire to explain shortly why it works.
When the project is being compiled and packaged, all the files and subdirs from 'src/main/java' in the project goes to the root directory of the packaged jar (the artifact we want to create). The same rule applies to 'src/main/resources'.
This is a convention respected by many tools like maven or sbt in process of building project (note: as a default configuration!). When code (from the post) was in running mode, it couldn't find nothing like "src/main/resources/beans.xml" due to the fact, that beans.xml was in the root of jar (copied to /beans.xml in created jar/ear/war).
When using ClassPathXmlApplicationContext, the proper location declaration for beans xml definitions, in this case, was "/beans.xml", since this is path where it belongs in jar and later on in classpath.
It can be verified by unpacking a jar with an archiver (i.e. rar) and see its content with the directories structure.
I would recommend reading articles about classpath as supplementary.
Try this:
new ClassPathXmlApplicationContext("file:src/main/resources/beans.xml");
file: preffix point to file system resources, not classpath.
file path can be relative or system (/home/user/Work/src...)
I also had a similar problem but because of a bit different cause so sharing here in case it can help anybody.
My file location
How I was using
ClassPathXmlApplicationContext("beans.xml");
There are two solutions
Take the beans.xml out of package and put in default package.
Specify package name while using it viz.
ClassPathXmlApplicationContext("com/mypackage/beans.xml");
src/main/resources is a source directory, you should not be referencing it directly. When you build/package the project the contents will be copied into the correct place for your classpath. You should then load it like this
new ClassPathXmlApplicationContext("beans.xml")
Or like this
new GenericXmlApplicationContext("classpath:beans.xml");
This is because applicationContect.xml or any_filename.XML is not placed under proper path.
Trouble shooting Steps
1: Add the XML file under the resource folder.
2: If you don't have a resource folder. Create one by navigating new by Right click on the project new > Source Folder, name it as resource and place your XML file under it.
use it
ApplicationContext context = new FileSystemXmlApplicationContext("Beans.xml");
You have looked at src directory. The xml file indeed exist there. But look at class or bin/build directory where all your output classes are set. I suspect you will need only resources/beans.xml path to use.
I suspect you're building a .war/.jar and consequently it's no longer a file, but a resource within that package. Try ClassLoader.getResourceAsStream(String path) instead.
Note that the first applicationContext is loaded as part of web.xml; which is mentioned with the below.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>META-INF/spring/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>myOwn-controller</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>META-INF/spring/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Where as below code will also tries to create one more applicationContext.
private static final ApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml");
See the difference between beans.xml and applicationContext.xml
And if appliationContext.xml under <META-INF/spring/> has declared with <import resource="beans.xml"/> then this appliationContext.xml is loading the beans.xml under the same location META-INF/spring of appliationContext.xml.
Where as; in the code; if it is declared like below
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
This is looking the beans.xml at WEB-INF/classes OR in eclipse src/main/resources.
[If you have added beans.xml at src/main/resources then it might be placed at WEB-INF/classes while creating the WAR.]
So totally TWO files are looked up.
I have resolved this issue by adding classpath lookup while importing at applicationContext.xml like below
<import resource="classpath*:beans.xml" />
and removed the the line ClassPathXmlApplicationContext("beans.xml") in java code, so that there will be only one ApplicationContext loaded.
In Spring all source files are inside src/main/java. Similarly, the resources are generally kept inside src/main/resources. So keep your spring configuration file inside resources folder.
Make sure you have the ClassPath entry for your files inside src/main/resources as well.
In .classpath check for the following 2 lines. If they are missing add them.
<classpathentry path="src/main/java" kind="src"/>
<classpathentry path="src/main/resources" kind="src" />
So, if you have everything in place the below code should work.
ApplicationContext ctx = new ClassPathXmlApplicationContext("Spring-Module.xml");
Gradle : v4.10.3
IDE : IntelliJ
I was facing this issue when using gradle to run my build and test. Copying the applicationContext.xml all over the place did not help. Even specifying the complete path as below did not help !
context = new ClassPathXmlApplicationContext("C:\\...\\applicationContext.xml");
The solution (for gradle at least) lies in the way gradle processes resources. For my gradle project I had laid out the workspace as defined at https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_project_layout
When running a test using default gradle set of tasks includes a "processTestResources" step, which looks for test resources at C:\.....\src\test\resources (Gradle helpfully provides the complete path).
Your .properties file and applicationContext.xml need to be in this directory. If the resources directory is not present (as it was in my case), you need to create it copy the file(s) there. After this, simply specifying the file name worked just fine.
context = new ClassPathXmlApplicationContext("applicationContext.xml");
Beans.xml or file.XML is not placed under proper path. You should add the XML file under the resource folder, if you have a Maven project.
src -> main -> java -> resources
I did the opposite of most. I am using Force IDE Luna Java EE and I placed my Beans.xml file within the package; however, I preceded the Beans.xml string - for the ClassPathXMLApplicationContext argument - with the relative path. So in my main application - the one which accesses the Beans.xml file - I have:
ApplicationContext context =
new ClassPathXmlApplicationContext("com/tutorialspoin/Beans.xml");
I also noticed that as soon as I moved the Beans.xml file into the package from the src folder, there was a Bean image at the lower left side of the XML file icon which was not there when this xml file was outside the package. That is a good indicator in letting me know that now the beans xml file is accessible by ClassPathXMLAppllicationsContext.
This is what worked for me:
new ClassPathXmlApplicationContext("classpath:beans.xml");
If this problem is still flummoxing you and you are developing using Eclipse, have a look at this Eclipse bug: Resources files from "src/main/resources" are not correctly included in classpath
Solution seems to be look at properties of project, Java build path, source folders. Delete the /src/main/resources dir and add it again. This causes Eclipse to be reminded it needs to copy these files to the classpath.
This bug affected me when using the "Neon" release of Eclipse. (And was very frustrating until I realized the simple fix just described)
I was experiencing this issue and it was driving me nuts; I ultimately found the following lying in my POM.xml, which was the cause of the problem:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
I was not sure to write it but maybe someone save a few hours:
mvn clean
may do the job if your whole configuration is already perfect!
I have stuck in this issue for a while and I have came to the following solution
Create an ApplicationContextAware class (which is a class that implements the ApplicationContextAware)
In ApplicationContextAware we have to implement the one method only
public void setApplicationContext(ApplicationContext context) throws BeansException
Tell the spring context about this new bean (I call it SpringContext)
bean id="springContext" class="packe.of.SpringContext" />
Here is the code snippet
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class SpringContext implements ApplicationContextAware {
private static ApplicationContext context;
#Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
public static ApplicationContext getApplicationContext() {
return context;
}
}
Then you can call any method of application context outside the spring context for example
SomeServiceClassOrComponent utilityService SpringContext.getApplicationContext().getBean(SomeServiceClassOrComponent .class);
I hope this will solve the problem for many users
I am on IntelliJ and faced the same issue. Below is how i resolved it:
1. Added the resource import as following in Spring application class along with other imports: #ImportResource("applicationContext.xml")
2. Saw IDE showing : Cannot resolve file 'applicationContext.xml' and also suggesting paths where its expecting the file (It was not the resources where the file applicationContext.xml was originally kept)
3. Copied the file at the expected location and the Exception got resolved.
Screen shot below for easy ref:
But if you would like to keep it at resources then follow this great answer link below and add the resources path so that it gets searched. With this setting exception resolves without #ImportResource described in above steps:
https://stackoverflow.com/a/24843914/5916535
Sharing my case and how I debugged it, maybe helps someone:
this will only be relevant if you have first checked you actually have the resources folder in correct place and correctly named
create some temporary folder somewhere, preferably out of any git projects (e.g. mkdir playground) and move there (cd playground)
copy the java archive there (e.g. cp /path/to/java.war .) that is missing that beans.xml
unpack it (e.g. unzip java.war on ubuntu)
find if there's any .xml files in there (for example in WEB-INF/classes) (the unpacking process should show a list of files being unpacked, most of them will probably be other dependencies as archives, these are not relevant)
if you don't see a beans.xml, just read the other .xml files (e.g. cat root-config.xml), you might find something like root-config.xml there or similar, in there you might either have some other <import resource="somethingelse.xml"> records or nothing.
if this is the case, this means you do have that file (root-config.xml here) present in the project or if not, continue going up parent projects to where the archive is getting packaged from. Find that file, add <import resource="beans.xml"> and run mvn package.
Now verifying the fix by doing the steps in 1.-5. should result in that file (root-config.xml here) in the newly packaged archive having the beans.xml defined and once you deploy it, it should work.
Make sure that beans.xml is located in the resources folder.
I have a Maven project that I'm trying to package as both a war and a jar. As part of my application / servlet initialisation (depending on whether I'm running the jar or the war), I need to read a file called server.ini. I've put the file in src/main/resources/server.ini and am trying to load it like so:
System.class.getResourceAsStream("server.ini");
However, this always results in null. What am I doing wrong?
The server.ini file should be in the root of a resources directory.
By placing it in the webapp you're making the file available via http, but you need it accessible on the classpath, which means that you should place it in the resources directory.
There's a good chance web.xml or context.xml is better suited to what you're trying to do, but...
Try putting server.ini in WEB-INF/classes, or do something like this.
The issue was that I was using the System classloader with an unqualified path, so it was expecting to find my server.ini in the java.lang package.
Since my file is in src/main/resources, I should just use the classloader of my current class, with an absolute path:
getClass().getResourceAsStream("/server.ini")
This works in both the war and the jar.
The "Preferred way of loading resources in Java" question has a great explanation of resource loading.
I am trying to deploy my web application on jboss-6.0.0Final, which is currently deployed on apache tomcat.
I have two jars one that contains same package which is org.apache.axis. I am putting one jar in <Jboss-home>/server/default/lib & another jar in <my-app-war>WEB-INF/lib.
It is required to put both jars in the class path. No way to remove one of the jar. So I need to keep both jars. & It is giving me following error
java.lang.ClassCastException: org.apache.axis.attachments.AttachmentsImpl cannot be cast to org.apache.axis.attachments.Attachments
at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
at org.apache.axis.client.Call.invoke(Call.java:1828)
I think it is due to conflict of same classes in two different jars.
Now, I want to know the way by which I can force jboss to load classes of this particular package from axis.jar exist in /WEB-INF/lib.
How can I do that?
This helped me:
http://www.mastertheboss.com/jboss-configuration/solving-jboss-5-classloading-issues
Explode your war,
In your Exploded WAR web-inf directory add this xml file: jboss-classloading.xml
with content:
(domain is your war name)
<classloading xmlns="urn:jboss:classloading:1.0"
name="mywar.war"
domain="mywar_domain" <!-- (domain is your war name) -->
parent-domain="Ignored"
export-all="NON_EMPTY"
import-all="true">
</classloading>
I'll share quite simple and straight forward process which I had followed when I came across same situation.
1> Create a jboss-web.xml file.
<class-loading java2classloadingcompliance="false">
<loader-repository>
com.rts:archive=DTH_PROD.war
<loader-repository-config>
java2ParentDelegation=false
</loader-repository-config>
</loader-repository>
</class-loading>
</jboss-web>
Points:,
Begin the xml with tag which is not visible in the code I'm posting
Check 3rd line of above code,
com.rts - This is your package name.
DTH_PROD.war - Name of bundle you wish to keep
2> Now place this xml file into WEB-INF directory of your project and voilla!!
Further more you may wish to refer this article for detailed info. Also comment below if you face any difficulty solving this.
I wrote a web service project using netbeans 6.7.1 with glassfish v2.1, put log4j.properties to the root dir of project and use:
static Logger logger = Logger.getLogger(MyClass.class);
in Constructor:
PropertyConfigurator.configure("log4j.properties");
and in functions:
logger.info("...");
logger.error("...");
// ...
but, it is error info(actually, I have tried to put it almost every dir that I could realize):
log4j:ERROR Could not read configuration file [log4j.properties].
java.io.FileNotFoundException: log4j.properties (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.io.FileInputStream.<init>(FileInputStream.java:66)
at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:297)
at org.apache.log4j.PropertyConfigurator.configure(PropertyConfigurator.java:315)
at com.corp.ors.demo.OrsDemo.main(OrisDemo.java:228)
log4j:ERROR Ignoring configuration file [log4j.properties].
log4j:WARN No appenders could be found for logger (com.corp.ors.demo.OrsDemo).
log4j:WARN Please initialize the log4j system properly.
the example project could be get from http://www.91files.com/?N3F0QGQPWMDGPBRN0QA8
I know it's a bit late to answer this question, and maybe you already found the solution, but I'm posting the solution I found (after I googled a lot) so it may help a little:
Put log4j.properties under WEB-INF\classes of the project as mentioned previously in this thread.
Put log4j-xx.jar under WEB-INF\lib
Test if log4j was loaded: add -Dlog4j.debug # the end of your java options of tomcat
Hope this will help.
rgds
As already stated, log4j.properties should be in a directory included in the classpath, I want to add that in a mavenized project a good place can be src/main/resources/log4j.properties
You can specify config file location with VM argument -Dlog4j.configuration="file:/C:/workspace3/local/log4j.properties"
You have to put it in the root directory, that corresponds to your execution context.
Example:
MyProject
src
MyClass.java
log4j.properties
If you start executing from a different project, you need to have that file in the project used for starting the execution. For example, if a different project holds some JUnit tests, it needs to have also its log4j.properties file.
I suggest using log4j.xml instead of the log4j.properties. You have more options, get assistance from your IDE and so on...
For a Maven Based Project keep your log4j.properties in src/main/resources. Nothing else to do!
If you put log4j.properties inside src, you don't need to use the statement -
PropertyConfigurator.configure("log4j.properties");
It will be taken automatically as the properties file is in the classpath.
Try:
PropertyConfigurator.configure(getClass().getResource("/controlador/log4j.properties"));
The file should be located in the WEB-INF/classes directory.
This directory structure should be packaged within the war file.
My IDE is NetBeans. I put log4j.property file as shown in the pictures
Root
Web
WEB-INF
To use this property file you should to write this code:
package example;
import java.io.File;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Logger;
import javax.servlet.*;
public class test {
public static ServletContext context;
static Logger log = Logger.getLogger("example/test");
public test() {
String homeDir = context.getRealPath("/");
File propertiesFile = new File(homeDir, "WEB-INF/log4j.properties");
PropertyConfigurator.configure(propertiesFile.toString());
log.info("This is a test");
}
}
You can define static ServletContext context from another JSP file.
Example:
test.context = getServletContext();
test sample = new test();
Now you can use log4j.property file in your projects.
A few technically correct specific answers already provided but in general, it can be anywhere on the runtime classpath, i.e. wherever classes are sought by the JVM.
This could be the /src dir in Eclipse or the WEB-INF/classes directory in your deployed app, but it's best to be aware of the classpath concept and why the file is placed in it, don't just treat WEB-INF/classes as a "magic" directory.
I've spent a great deal of time to figure out why the log4j.properties file is not seen.
Then I noticed it was visible for the project only when it was in both MyProject/target/classes/ and MyProject/src/main/resources folders.
Hope it'll be useful to somebody.
PS: The project was maven-based.
I found that Glassfish by default is looking at [Glassfish install location]\glassfish\domains[your domain]\ as the default working directory... you can drop the log4j.properties file in this location and initialize it in your code using PropertyConfigurator as previously mentioned...
Properties props = System.getProperties();
System.out.println("Current working directory is " + props.getProperty("user.dir"));
PropertyConfigurator.configure("log4j.properties");
Your standard project setup will have a project structure something like:
src/main/java
src/main/resources
You place log4j.properties inside the resources folder, you can create the resources folder if one does not exist
I don't know this is correct way.But it solved my problem.
put log4j.properties file in "project folder"/config and use PropertyConfigurator.configure("config//log4j.properties");
it will works with IDE but not when run the jar file yourself.
when you run the jar file by yourself just copy the log4j.properties file in to the folder that jar file is in.when the jar and property file in same directory it runs well.
Put log4j.properties in classpath.
Here is the 2 cases that will help you to identify the proper location-
1. For web application the classpath is /WEB-INF/classes.
\WEB-INF
classes\
log4j.properties
To test from main / unit test the classpath is source directory
\Project\
src\
log4j.properties
There are many ways to do it:
Way1: If you are trying in maven project without Using PropertyConfigurator
First:
check for resources directory at scr/main
if available,
then: create a .properties file and add all configuration details.
else
then: create a directory named resources and a file with .properties
write your configuration code/details.
follows the screenshot:
Way2: If you are trying with Properties file for java/maven project Use PropertyConfigurator
Place properties file anywhere in project and give the correct path.
say: src/javaLog4jProperties/log4j.properties
static{
PropertyConfigurator.configure("src/javaLog4jProperties/log4j.properties");
}
Way3: If you are trying with xml on java/maven project Use DOMConfigurator
Place properties file anywhere in project and give correct path.
say: src/javaLog4jProperties/log4j.xml
static{
DOMConfigurator.configure("src/javaLog4jProperties/log4j.xml");
}
For me, it worked when I put the file inside the resources folder.
Also, it was a war file for my project. My recommendation is to ensure that the name of the file is log4j.properties, as my project didn't recognize "log4j2.properties"
Actually, I've just experienced this problem in a stardard Java project structure as follows:
\myproject
\src
\libs
\res\log4j.properties
In Eclipse I need to add the res folder to build path, however, in Intellij, I need to mark the res folder as resouces as the linked screenshot shows: right click on the res folder and mark as resources.
You don't need to specify PropertyConfigurator.configure("log4j.properties"); in your Log4J class, If you have already defined the log4j.properties in your project structure.
In case of Web Dynamic Project: -
You need to save your log4j.properties under WebContent -> WEB-INF -> log4j.properties
I hope this may help you.
Open spark-shell
Then type System.getenv("SPARK_CONF_DIR")
That will print where your log4j.properties should go.
In Java, you often see a META-INF folder containing some meta files. What is the purpose of this folder and what can I put there?
From the official JAR File Specification (link goes to the Java 7 version, but the text hasn't changed since at least v1.3):
The META-INF directory
The following files/directories in the META-INF directory are recognized and interpreted by the Java 2 Platform to configure applications, extensions, class loaders and services:
MANIFEST.MF
The manifest file that is used to define extension and package related data.
INDEX.LIST
This file is generated by the new "-i" option of the jar tool, which contains location information for packages defined in an application or extension. It is part of the JarIndex implementation and used by class loaders to speed up their class loading process.
x.SF
The signature file for the JAR file. 'x' stands for the base file name.
x.DSA
The signature block file associated with the signature file with the same base file name. This file stores the digital signature of the corresponding signature file.
services/
This directory stores all the service provider configuration files.
New since Java 9 implementing JEP 238 are multi-release JARs. One will see a sub folder versions. This is a feature which allows to package classes which are meant for different Java version in one jar.
Generally speaking, you should not put anything into META-INF yourself. Instead, you should rely upon whatever you use to package up your JAR. This is one of the areas where I think Ant really excels: specifying JAR file manifest attributes. It's very easy to say something like:
<jar ...>
<manifest>
<attribute name="Main-Class" value="MyApplication"/>
</manifest>
</jar>
At least, I think that's easy... :-)
The point is that META-INF should be considered an internal Java meta directory. Don't mess with it! Any files you want to include with your JAR should be placed in some other sub-directory or at the root of the JAR itself.
I've noticed that some Java libraries have started using META-INF as a directory in which to include configuration files that should be packaged and included in the CLASSPATH along with JARs. For example, Spring allows you to import XML Files that are on the classpath using:
<import resource="classpath:/META-INF/cxf/cxf.xml" />
<import resource="classpath:/META-INF/cxf/cxf-extensions-*.xml" />
In this example, I'm quoting straight out of the Apache CXF User Guide. On a project I worked on in which we had to allow multiple levels of configuration via Spring, we followed this convention and put our configuration files in META-INF.
When I reflect on this decision, I don't know what exactly would be wrong with simply including the configuration files in a specific Java package, rather than in META-INF. But it seems to be an emerging de facto standard; either that, or an emerging anti-pattern :-)
The META-INF folder is the home for the MANIFEST.MF file. This file contains meta data about the contents of the JAR. For example, there is an entry called Main-Class that specifies the name of the Java class with the static main() for executable JAR files.
META-INF in Maven
In Maven the META-INF folder is understood because of the Standard Directory Layout, which by name convention package your project resources within JARs: any directories or files placed within the ${basedir}/src/main/resources directory are packaged into your JAR with the exact same structure starting at the base of the JAR.
The Folder ${basedir}/src/main/resources/META-INF usually contains .properties files while in the jar contains a generated MANIFEST.MF, pom.properties, the pom.xml, among other files. Also frameworks like Spring use classpath:/META-INF/resources/ to serve web resources.
For more information see How do I add resources to my Maven Project.
You can also place static resources in there.
In example:
META-INF/resources/button.jpg
and get them in web3.0-container via
http://localhost/myapp/button.jpg
> Read more
The /META-INF/MANIFEST.MF has a special meaning:
If you run a jar using java -jar myjar.jar org.myserver.MyMainClass you can move the main class definition into the jar so you can shrink the call into java -jar myjar.jar.
You can define Metainformations to packages if you use java.lang.Package.getPackage("org.myserver").getImplementationTitle().
You can reference digital certificates you like to use in Applet/Webstart mode.
Adding to the information here, the META-INF is a special folder which the ClassLoader treats differently from other folders in the jar.
Elements nested inside the META-INF folder are not mixed with the elements outside of it.
Think of it like another root. From the Enumerator<URL> ClassLoader#getSystemResources(String path) method et al perspective:
When the given path starts with "META-INF", the method searches for resources that are nested inside the META-INF folders of all the jars in the class path.
When the given path doesn't start with "META-INF", the method searches for resources in all the other folders (outside the META-INF) of all the jars and directories in the class path.
If you know about another folder name that the getSystemResources method treats specially, please comment about it.
Just to add to the information here, in case of a WAR file, the META-INF/MANIFEST.MF file provides the developer a facility to initiate a deploy time check by the container which ensures that the container can find all the classes your application depends on. This ensures that in case you missed a JAR, you don't have to wait till your application blows at runtime to realize that it's missing.
I have been thinking about this issue recently. There really doesn't seem to be any restriction on use of META-INF. There are certain strictures, of course, about the necessity of putting the manifest there, but there don't appear to be any prohibitions about putting other stuff there.
Why is this the case?
The cxf case may be legit. Here's another place where this non-standard is recommended to get around a nasty bug in JBoss-ws that prevents server-side validation against the schema of a wsdl.
http://community.jboss.org/message/570377#570377
But there really don't seem to be any standards, any thou-shalt-nots. Usually these things are very rigorously defined, but for some reason, it seems there are no standards here. Odd. It seems like META-INF has become a catchall place for any needed configuration that can't easily be handled some other way.
If you're using JPA1, you might have to drop a persistence.xml file in there which specifies the name of a persistence-unit you might want to use. A persistence-unit provides a convenient way of specifying a set of metadata files, and classes, and jars that contain all classes to be persisted in a grouping.
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
// ...
EntityManagerFactory emf =
Persistence.createEntityManagerFactory(persistenceUnitName);
See more here:
http://www.datanucleus.org/products/datanucleus/jpa/emf.html
All answers are correct. Meta-inf has many purposes. In addition, here is an example about using tomcat container.
Go to
Tomcat Doc and check
" Standard Implementation > copyXML " attribute.
Description is below.
Set to true if you want a context XML descriptor embedded inside the application (located at /META-INF/context.xml) to be copied to the owning Host's xmlBase when the application is deployed. On subsequent starts, the copied context XML descriptor will be used in preference to any context XML descriptor embedded inside the application even if the descriptor embedded inside the application is more recent. The flag's value defaults to false. Note if the deployXML attribute of the owning Host is false or if the copyXML attribute of the owning Host is true, this attribute will have no effect.
You have MANIFEST.MF file inside your META-INF folder. You can define optional or external dependencies that you must have access to.
Example:
Consider you have deployed your app and your container(at run time) found out that your app requires a newer version of a library which is not inside lib folder, in that case if you have defined the optional newer version in MANIFEST.MF then your app will refer to dependency from there (and will not crash).
Source: Head First Jsp & Servlet
As an addition the META-INF folder is now also used for multi-release jars. This is a feature which allows to package classes which are meant for different Java version in one jar, e.g. include a class for Java 11 with new features offered by Java 11 in a jar also working for Java 8, where a different class for Java 8 with less features in contained. E.g this can be useful if a newer Java version is offering enhanced, different or new API methods which would not work in earlier version due to API violations. One will see a sub folder versions then.