I have a property file that is bundled in an external jar file in my WEB-INF/lib. If I want to override the values in that property file and use my own values from my own property file. Is there a better way to do it.
For example:
in the default property file, I see
banner.ad.link={0}
I want to change it to something like:
banner.ad.link=<a class="mycss" href="{1}" title="Click here {0}">{0}</a>
So far this is what I have:
public class MainListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent event)
{
ResourceBundle bundle = ResourceBundle.getBundle("com.comResources");
bundle = ResourceBundle.getBundle("org.displaytag.messages",
Locale.getDefault());
for (Enumeration<String> e = bundle.getKeys(); e.hasMoreElements() ;) {
System.out.println(e.nextElement());
}
}
}
I'm not too sure where to go from here to override the key value pair from the bundle object to have a new value from my own property file. Any help, I would be greatly appriciated! Thanks in advance!
I see three ways of doing it.
just put your properties file in the classpath, but before the properties file that you want to override. Putting it in WEB-INF/classes should work.
Change the jar file and remove the properties file from it
Create a class having the same basename as the properties file, and delegate to your properties file in the class to implement the bundle. See The ResourceBundle api doc to understand how resource bundles are loaded. The class file will be loaded before the properties file for a given bundle base name and locale.
Note that if all you want to do is to customize displaytag, you just have to put your displaytag.properties at the root of the classpath (i.e. in the default package) rather than in the org.displaytag.properties package, as documented here. Displaytag will load your bundle rather than the default one if found.
Related
I have some placeholders in my flow. Values for these placeholders are specified in a properties file (in classpath). I am doing munit using java. Currently, these placeholders are not getting replaced by values in property file. Any idea how do I load this file while running munit?
My munit is like this:
Class MyClass extends FunctionalMunitSuite{
#Override
protected String getConfigResources() {
//try 1[gave give value pairs directly]: didnt worked
System.getProperties().put("prop.key", "value");
//try2[load prop files]:didn't worked
prop.load(this.getClass().getResourceAsStream("mypropertyfile.properties"));
System.setProperties(prop);
}
}
In Overriding getConfigResources() specify a test-config.xml which has your mock connector and context property placeholder of properties file. Store that test properties file in src/test/resources
#Override
protected String getConfigResources() {
return "mule-config-test.xml" + ",actual-flow-to-test.xml";
}
Inside mule-config-test.xml, define test property file like this:
<context:property-placeholder ignore-resource-not-found="true" location="wmo-mule-app.properties,wmo-mule-app-unit-test.properties" />
In this case, wmo-mule-app.properties is my actual app property file while wmo-mule-app-unit-test.properties is the over-riding unit-test property file. This unit-test property file will take precedence over wmo-mule-app.properties
Currently you might be having your files in /src/main/resources
try to put it in /src/test/resources
I need to have a jar file located in a main/assets directory within an Android project. It is important the jar file is located there.
With my main Android project is there a way to reference this jar file in my code and to use its classes?
To be clear I don't want to add the jar to the main project once compiled.
EDIT: I have tried the link below and it seems to load the Class file I've stated. But I'm strugging how to define constructor arguments for the dynamically loaded Class.
android-custom-class-loading-sample
EDIT2
Nearly there. I've confirmed the class is loaded from my classes.jar. I'm stuck instantiating it though.
On the licenseValidatorClazz.getConstructor line I get the error below. I'm guessing I'm missing something from my Interface file?
java.lang.NoSuchMethodException: [interface com.google.android.vending.licensing.Policy, interface com.google.android.vending.licensing.DeviceLimiter, interface com.google.android.vending.licensing.LicenseCheckerCallback, int, class java.lang.String, class java.lang.String]
public Class licenseValidatorClazz = null;
public LicenseValidator validator;
...
// Initialize the class loader with the secondary dex file.
DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(),
null,
mContext.getClassLoader());
try {
// Load the library class from the class loader.
licenseValidatorClazz = cl.loadClass("com.google.android.vending.licensing.LicenseValidator");
validator = (LicenseValidator) licenseValidatorClazz.getConstructor(Policy.class,DeviceLimiter.class,LicenseCheckerCallback.class,int.class,String.class,String.class).newInstance(ddd, new NullDeviceLimiter(),
callback, generateNonce(), mPackageName, mVersionCode);
} catch (Exception exception) {
// Handle exception gracefully here.
exception.printStackTrace();
}
I have an Interface which contains the functions to pass to the loaded class.
public interface LicenseValidator
{
public LicenseCheckerCallback getCallback();
public int getNonce();
public String getPackageName();
public void verify(PublicKey publicKey, int responseCode, String signedData, String signature);
public void handleResponse(int response, ResponseData rawData);
public void handleApplicationError(int code);
public void handleInvalidResponse();
}
TO use an external jar to be associated with your application and use it during runtime, it needs to be in dalvik format since normal jars cannot work under dalvikVM.
Convert your files using the dx tool
using aapt cmd , add those classes.dex to your jar file.
Now this jar which contains files in dalvik format can be loaded into our project.
Here is a post which explains the procedure to accomplish it.
There are steps to accomplish this.
You have to make a copy of your JAR file into the private internal storage of your aplication.
Using the dx tool inside the android folder, you have to generate a classes.dex file associated with the JAR file. The dx tool will be at the location /android-sdks/build-tools/19.0.1 (this file is needed by the Dalvik VM, simply jar can not be read by the dalvik VM))
Using the aapt tool command which is also inside the same location, you have to add the classes.dex to the JAR file.
This JAR file could be loaded dynamically using DexClassLoader.
If you are making a JAR from any one your own library, you have to do this steps (1-4) every time when there is a change in your library source code. So you can automate this steps by creating a shell script(in Mac/Linux/Ubuntu) or batch scripts(in Windows). You can refere this link to understand how to write shell scripts.
Note : One situation for implementing this method is, when it is impossible to add the JAR files directly to the build path of core project and need to be loaded dynamically at run time. In normal cases the JAR files could be added to the build path.
please check this link for the detailed code and implementation.
How to load a jar file at runtime
Android: How to dynamically load classes from a JAR file?
Hope this helps!!
You should try out the Services API - java.util.ServiceLoader
You define a service interface and its implementations in your jar.
package com.my.project;
public interface MyService { ... }
public class MyServiceBarImpl implements MyService { ... }
public class MyServiceFooImpl implements MyService { ... }
Then you define the services contained within the jar file in the META-INF/services/ directory. For instance, in the file 'META-INF/services/com.my.project.MyService', you list the provider classes.
# Known MyService providers.
com.my.project.MyServiceBarImpl # The original implementation for handling "bar"s.
com.my.project.MyServiceFooImpl # A later implementation for "foo"s.
Then, in your main codebase, you can instantiate a MyService instance with the ServiceLoader:
for (MyService service : ServiceLoader.load(MyService.class)) {
//Perform some test to determine which is the right MyServiceImpl
//and then do something with the MyService instance
}
These examples are taken more-or-less straight from the API, although I've changed the package names to make them slightly less annoying to read.
I have a properties file myprops.properties as follows:
Wsdl=someurl
UserName=user
UserPassword=pasword
Application=appName
And inside my controller I'm trying to access to set values in my service as follows
Properties prop = new Properties();
prop.load(new FileInputStream("resources/myprops.properties"));
myService.setWsdl(prop.getProperty("Wsdl"));
myService.setUserName(prop.getProperty("UserName"));
myService.setUserPassword(prop.getProperty("UserPassword"));
myService.setApplication(prop.getProperty("Application"));
my Issue is I just do not know what path to use. Its a Spring project if that makes any difference. and Idealy I would like to have the properties file in my "src/main/resources" folder
I realise this may be very simple to some but I have tried searching for the solution both here and on Google and I cannot seem to find a solution that has helped. I've tried moving the file around the project but cannot seem to figure it out
The Error I get is
java.io.FileNotFoundException: resources\drm.properties (The system cannot find the path specified)
any advice/explanation or even a link that clearly explains it would be great
well, src/main/resources are on the classpath, you just need to do.
Properties properties = PropertiesLoaderUtils.loadAllProperties("your properties file name");
If you are using spring, you could set your property placeholder.
<context:property-placeholder location="classpath:resources/myprops.properties" />
and in your beans you can inject the values from the properteis using the #Value annotation
#Autowired
public Foo(#Value("${Wsdl}") String wsdl) {
...
}
in the case above I used in the constructor, but its possible to use by Autowired field/setter.
So in your service you could have something like:
#Service
public class MyService {
private final String wsdl;
private final String username;
private final String password;
private final String application;
#Autowired
public MyService(
#Value("${Wsdl}") String wsdl,
#Value("${UserName}") String username,
#Value("${UserPassword}") String password,
#Value("${Application}") String application
) {
// set it to each field.
}
}
Given that src/main/resources is on the classpath, you could do:
Resource resource = new ClassPathResource("/myprops.properties");
Properties props = PropertiesLoaderUtils.loadProperties(resource);
Don't use a FileInputStream; use getResourceAsStream() to read it from the servlet context.
You can always count on mkyong. This is an example/tutorial on how to load and read property files.
http://www.mkyong.com/java/java-properties-file-examples/
This question should be marked as a duplicate:
Loading a properties file from Java package
How to use Java property files?
Load a property file in Java
Java Properties File not loading
Java NullPointerException on loading properties file
Not able to load properties file in Java
I'm trying to use a resource from another module to import a file. My goal is to pass the filename by each custom class, and let the base class of another module fetch the file.
But I always get a Nullpointer Exception.
What am I doing wrong?
Module A:
src/main/java/foo/bar/MyBaseClass.java
src/main/resources/foo/bar/test.xml
Module B:
src/main/java/other/path/MyCustomClass extends MyBaseClass
classes:
abstract class MyBaseClass {
public static String TESTFILE = "foo/bar/test.xml";
getData(String filename) {
InputStream inputStream = MyBaseClass.class.getResourceAsStream(String filename); //NPE
}
}
class MyCustomClass extends MyBaseClass() {
doSomething() {
getData(TESTFILE);
}
}
/edit:
should I maybe use something like this?
super.getClass().getResourceAsStream(..)
It's very likely you should be using ClassLoader.getResourceAsStream()
e.g.
Thread.currentThread().getContextClassLoader().getResourceAsStream()
(probably safer, might work in different environments more correctly, i.e., where a special classloader is being used, Java EE?)
or at least
aClass.getClassLoader().getResourceAsStream()
this is how you should load resources on the classpath which may be in a different JAR (or classpath entry) than the given class you're calling getResourceXXX on.
If you're using a class that's in module B and you want to load resources from module A, you need to use ClassLoader.getResourceXXX.
So in Java you should generally use this approach (unless you care about restricting resource loading to a smaller area...)
Another thing to be careful about: pay attention to the need for a leading "/", always double-check the javadocs of whichever method you're using
see also: http://www.xyzws.com/servletfaq/what-is-different-between-classloadergetresourceasstream-and-classgetresourceasstream/21
The getResourcesAsStream() expects a name which is NOT a filename cause it's a resource name. Furthermore it looks like you are trying to access a resource from an other maven module. And not to forget you are trying to access the resource via a relative path which should be changed into an absolute resources path like /foo/bar/test.xml instead of foo/bar/test.xml.
I have my .properties file in
com.someOtherpage
-somefolder
--theProperties.java `<--- This guy needs it`
com.somepackage
WEB-INF
-config
--project.properties `<--- Here is where he sits`
when deployed how can I call the properties file with out calling its absolute path like below
public class theProperties
{
private static Properties properties = new Properties();
public theProperties()
{
}
public String get(String attribute) throws Exception
{
//what do I need to set up to be able to call this file this way
//notice there is no '../../project.properties'
// -----
InputStream is = theProperties.class.getResourceAsStream("project.properties");
properties.load(is);
is.close();
return properties.getProperty(attribute);
}
}
The above isn't working, why?
If you put the properties file in the same package as the Class that reads it you specify its path relative to that class, that is if the properties file is in the exact same package as the class loading it you specify the path as project.properties.
If you put the properties file in the default package and the loading class isn't in the default package, you have to specify an absolute path like, /project.properties. Just a reminder no classes should be in the default class path as a general rule.
Either way, your properties file has to be on the classpath which yours isn't. In other words it has to be somewhere in WEB-INF/classes/.
A better solution, but more complex is to use Guice to inject properties and not write your own reader.
here is a nice explanation of how...
http://jaitechwriteups.blogspot.com/2007/01/how-to-read-properties-file-in-web.html
Assuming you want to avoid the absolute filepath, not the absolute path within the classpath, you need to do:
theProperties.class.getResourceAsStream("/WEB-INF/config/project.properties")
The forward slash at the front is important. Without it the path is relative to the loading class's package location.