I am trying a simple example of i18n in java but i am getting Can't find bundle for base name Resources/MessageBundle, locale en_US
This is my code
import java.util.ResourceBundle;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
ResourceBundle myResources =
ResourceBundle.getBundle("Resources/MessagesBundle");
for (String s : myResources.keySet())
{
System.out.println(s);
}
// TODO Auto-generated method stub
}
}
And this is my project structure http://oi62.tinypic.com/x5y4y8.jpg
Can anyone help me with this.I have added resource folder to java Build path
If you add the Resources directory to your build path, then this directory has to be considered as a root. Therefore, you'll find your bundle with :
ResourceBundle myResources =
ResourceBundle.getBundle("MessageBundle");
You have to know that ResourceBundle works with class loader, and the build path (or class path) sets the root of the class loader path.
You do not need the Resources/
ResourceBundle.getBundle("MessageBundle");
From javadoc :
baseName - the base name of the resource bundle, a fully qualified class name
As Resources seems to be in your class path, it should work.
Related
My aim is to use the java.util.logging Level class and change the Level strings like 'FINE' to 'VERBOSE'.
public static final Level FINE = new Level("FINE", 500);
I know we can do this by extending the Level as follows:
public class MyLogLevel extends Level {
private static final long serialVersionUID = -8176160795706313070L;
private static final Level FINE = new MyLogLevel("VERBOSE", 500);
protected MyLogLevel(String name, int level) {
super(name, level);
}
}
I would like to know, is this the good way to do it or are there any better ways to do it.
If you are running Oracle JDK or OpenJDK you can simply override the localized names of the existing levels. You do this by creating new resource bundle (properties file or resource bundle class) under the package sun.util.logging.resources. The bundle name must be in the form of logging_LANG_COUNTRY.
For example, here is a test program under project called LevelTest:
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
public class NewLevels {
public static void main(String[] args) {
System.out.println(Locale.getDefault());
ResourceBundle rb = ResourceBundle.getBundle("sun.util.logging.resources.logging");
System.out.println(rb.getLocale());
System.out.println(Level.FINE.getLocalizedName());
System.out.println(Level.FINER.getLocalizedName());
System.out.println(Level.FINEST.getLocalizedName());
}
}
When I execute this test the locale printed is en_US. Therefore my resource bundle name will be logging_en_US.properties.
The properties resource bundle will contain the following:
FINE=VERBOSE
FINER=VERBOSE
FINEST=VERBOSE
Here is a listing of the project structure:
%USERPROFILE%\Documents\Projects\LevelTest\src\NewLevels.java
%USERPROFILE%\Documents\Projects\LevelTest\src\sun\util\logging\resources\logging_en_US.properties
When I run the program I get the following output:
en_US
en_US
VERBOSE
VERBOSE
VERBOSE
On a larger project, you might have to fight some of the class loader issues to ensure that the correct resource bundle is located.
Alternatively, if you don't want to do that you can resort to creating a custom formatter.
I am trying to use resource bundle in my project. i am new for development. is it professional way to put property files inside src/ folder i mean inside jar.
Also i have tried by placing my propert [AppProp] outside of the src folder [/resources/properties/AppProp]. I have added Add Class Folder from build path eclipse. I am trying to run this in eclipse. But it says Can't find bundle for base name. Please see my below code. Please provide any suggestion.
public class PropertyReader {
private String bundleName = null;
ResourceBundle resourceBundle = null;
public PropertyReader(String bundle){
this.bundleName = bundle;
loadProperty();
}
public void loadProperty(){
try{
resourceBundle = ResourceBundle.getBundle(bundleName);
} catch(Exception e){
e.printStackTrace();
}
}
public static void main(String a[]){
try{
PropertyReader pr = new PropertyReader("resources/properties/AppProp");
} catch(Exception e){
e.printStackTrace();
}
}
}
You don't need to change the code. But make sure following
1) You are providing the correct file path.
2) File type must be .properties in your case it should be be like AppProp.properties
There are lot of techniques/standards to organize your source files and code.
But for now above points are the solution of your problem.
Whenever I deploy a web app in tomcat, all the jars inside WEB-INF/lib will be loaded into application ClassLoader.
I have few other locations with some set/s of jars,like WEB-INF/ChildApp1/*.jar, WEB-INF/ChildApp2/*.jar.....
Based on user request I want to load some set of jars into current class loader.
Note : I don't want to create any child class loader.
My real requirement is, programmatically how to add jars into current class loader.
I did it once, but this is kinda hack. Please see the code below:
final URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
final Class<URLClassLoader> sysclass = URLClassLoader.class;
// TODO some kind of a hack. Need to invent better solution.
final Method method = sysclass.getDeclaredMethod("addURL", new Class[] { URL.class });
method.setAccessible(true);
for (final File jar : jars) {
method.invoke(sysloader, new URL[] { jar.toURI().toURL() });
}
You need to change ClassLoader.getSystemClassloader() to class loader you want to use. You also have to check if this is an instance of URLClassloader
I think there is better solution, but this worked for me
You will need to implement your own WebappClassLoaderBase to be defined in the configuration of the loader in the context.xml.
Implement your WebappClassLoaderBase
The simplest way is to extend WebappClassLoader as next
package my.package;
public class MyWebappClassLoader extends WebappClassLoader {
public MyWebappClassLoader() {
}
public MyWebappClassLoader(final ClassLoader parent) {
super(parent);
}
#Override
public void start() throws LifecycleException {
String[] paths = {"/WEB-INF/ChildApp1/lib", "/WEB-INF/ChildApp2/lib"};
// Iterate over all the non standard locations
for (String path : paths) {
// Get all the resources in the current location
WebResource[] jars = resources.listResources(path);
for (WebResource jar : jars) {
// Check if the resource is a jar file
if (jar.getName().endsWith(".jar") && jar.isFile() && jar.canRead()) {
// Add the jar file to the list of URL defined in the parent class
addURL(jar.getURL());
}
}
}
// Call start on the parent class
super.start();
}
}
Deploy your WebappClassLoaderBase
Build your own WebappClassLoaderBase using the tomcat jar corresponding to your tomcat version that is available from here.
Create a jar from it
And put the jar in tomcat/lib in order to make it available from the Common ClassLoader
Configure your WebappClassLoaderBase
Define your WebappClassLoaderBase in the context.xml
<Context>
...
<Loader loaderClass="my.package.MyWebappClassLoader" />
</Context>
It is done, now your webapps will be able to load jar files from /WEB-INF/ChildApp1/lib and /WEB-INF/ChildApp2/lib.
Response Update
As you would like to do the same thing but with only a war, you will need to use a hack to add dynamically your jar files.
Here is how you can proceed:
Implement a ServletContextListener to add your jar files
In order to add your jar files dynamically when the context is initialized, you need to create a ServletContextListener that will call URLClassLoader#addURL(URL) by refection which is an ugly hack but it works. Note that it works because the ClassLoader of a webapp in Tomcat is a WebappClassLoader which is actually a subclass of URLClassLoader.
package my.package;
public class MyServletContextListener implements ServletContextListener {
#Override
public void contextInitialized(final ServletContextEvent sce) {
try {
// Get the method URLClassLoader#addURL(URL)
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
// Make it accessible as the method is protected
method.setAccessible(true);
String[] paths = {"/WEB-INF/ChildApp1/lib", "/WEB-INF/ChildApp2/lib"};
for (String path : paths) {
File parent = new File(sce.getServletContext().getRealPath(path));
File[] jars = parent.listFiles(
new FilenameFilter() {
#Override
public boolean accept(final File dir, final String name) {
return name.endsWith(".jar");
}
}
);
if (jars == null)
continue;
for (File jar : jars) {
// Add the URL to the context CL which is a URLClassLoader
// in case of Tomcat
method.invoke(
sce.getServletContext().getClassLoader(),
jar.toURI().toURL()
);
}
}
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
#Override
public void contextDestroyed(final ServletContextEvent sce) {
}
}
Declare your ServletContextListener
In the web.xml of your webapp simply add:
<listener>
<listener-class>my.package.MyServletContextListener</listener-class>
</listener>
I have written a grammar that allows the user to input a relative path. (e.g. "../../temp/out/path"
May aim is to get the absolute path based on the input from the user, and the absolute path of the current working directory so that I can also check if the input path is valid or not.
Is there libraries or built in functions that I can use to get the absolute path?
Something similar to C's _getcwd() function.
Yes, Java has a File class. You can create one by calling this constructor which takes a String. Then you can call getAbsolutePath() on it. You can call it like this:
package com.sandbox;
import java.io.File;
public class Sandbox {
public static void main(String[] args) {
File file = new File("relative path");
String absolutePathString = file.getAbsolutePath();
}
}
This will print a complete absolute path from where your application has initialized.
public class JavaApplication1 {
public static void main(String[] args) {
System.out.println("Working Directory = " +System.getProperty("user.dir"));
}
}
Is there a (compatible, if possible) way to determine the absolute path of a loaded Class?
Of course, this is not always possible (if you think of dynamically created classes), but
if the loaded Class is inside a jar how to get the absolute path for this jar?
MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath()
Fullcode:
package org.life.java.so.questions;
/**
*
* #author jigar
*/
public class GetClassPath {
public static void main(String[] args) {
System.out.println(GetClassPath.class.getProtectionDomain().getCodeSource().getLocation().getPath());
}
}
Output:
/C:/Documents%20and%20Settings/argus/My%20Documents/NetBeansProjects/temp/build/classes/
Or
ClassLoader loader = GetClassPath.class.getClassLoader();
System.out.println(loader.getResource("org/life/java/so/questions/GetClassPath.class"));
Try something like this:
SomeClass.class.getResource("/" + SomeClass.class.getName() + ".class").toString();
If the class is loaded from jar the result should be something like:
jar://myjar.jar!path/to/SomeClass.class