Need to create a class that i can load properties in and be able to call required properties from that class. such as propertiesClass.getname();
Here's my Class so far. I can't seem to initiate the property load.
So what i need is from another class in the project to just do (currently getting null)
String url = TestProperties.getBaseUrl();
*updated the class, here's what it looks like now.
public class TestProperties {
private static Properties testProperties;
private static String instanceUrl;
public TestProperties() throws Exception{
loadProperties();
getInstanceProperties();
instanceUrl = TestProperties.testProperties.getProperty("confluence.base.url","");
}
public static String getBaseUrl(){
return instanceUrl;
}
private void loadProperties() throws IOException {
InputStream testPropertiesInput = this.getClass().getClassLoader().getResourceAsStream("smoketest.properties");
TestProperties.testProperties = new Properties();
// if (null != testProperties) {
try{
TestProperties.testProperties.load(testPropertiesInput);
} finally {
IOUtils.closeQuietly(testPropertiesInput);
}
// }
}
}
my otherclass(){
String myurl = TestProperties.getBaseUrl();
}
The method
public void TestProperties() throws Exception{
was meant to be constructor but isn't one, so the class only gets a default no-arg constructor. Change that to:
public TestProperties() throws Exception{
i.e. remove the return type as constructors are distinguished from ordinary methods by not declaring a return type.
Please make sure you are able to rightly access your properties file smoketest.properties though InputStream testPropertiesInput.
EDIT:
There is no need to redefine the local variable in loadProperties and return it. It can be written very simply as:
private static void loadProperties() throws IOException {
InputStream testPropertiesInput = getClass().getClassLoader()
.getResourceAsStream("smoketest.properties");
Properties testProperties = new Properties();
try{
TestProperties.testProperties.load(testPropertiesInput);
} finally {
IOUtils.closeQuietly(testPropertiesInput);
}
TestProperties.testProperties = testProperties;
}
I think public void TestProperties() throws Exception{ is constructor of your class. If yes, please remove void from it as it making it as a method.
Finally you may want to use testProperties in your TestProperties() constructor as :
public TestProperties() throws Exception{
loadProperties();
getInstanceProperties();
instanceUrl = TestProperties.testProperties
.getProperty("confluence.base.url","");
}
Please Note: I don't think your class variables should be defined as static. Is there any reason of doing so?
EDIT: Here is the hopefully working sample code for you:
public class TestProperties {
private static Properties testProperties;
private static String instanceUrl;
public TestProperties(){
try{
loadProperties();
//getInstanceProperties();
instanceUrl = TestProperties.testProperties
.getProperty("confluence.base.url","");
}catch(IOException ioe){
ioe.printStackTrace();
}
}
static{
//Just to initialize the properties
new TestProperties();
}
private void loadProperties() throws IOException {
InputStream testPropertiesInput = getClass().getClassLoader()
.getResourceAsStream("smoketest.properties");
Properties testProperties = new Properties();
try{
testProperties.load(testPropertiesInput);
} finally {
IOUtils.closeQuietly(testPropertiesInput);
}
TestProperties.testProperties = testProperties;
}
public static String getBaseUrl(){
return instanceUrl;
}
public static String getPropertyValue(String key){
return TestProperties.testProperties.getProperty(key,"Not Found");
}
}
Now you can simply get your base URL any where as :
public static void main(String[] args) {
System.out.println(TestProperties.getBaseUrl());
System.out.println(TestProperties.getPropertyValue("confluence.base.url"));
System.out.println(TestProperties.getPropertyValue("test.property"));
}
Related
In my project, I have a method which loads a big model from local disk. Loading the model takes about 15 minutes and sometimes more. What i'm thinking to do is to create a runnable method which loads the model for once and then, from different classes i call this method to execute some code.
in fact, i'm not sure how to achieve that, could you please guide me?
Here is simple pseudo code:
// class A has two method , load the model , and does some calculation
Class A: 1.Runnable method: LoadModel();
2.Mehtod2: distance();
// here i would like to run this programe anytime, pass some parameters and call the method "distance" in class A
Class B: 1.import Loadmodel() class and invoke distance ();
in my mind i'd like to create something similar to server but not server:)
Updated:The code below is what I've tried so far.
public class load implements Runnable {
WordVectors wordVectors;
public void run() {
try {
load();
} catch (FileNotFoundException ex) {
java.util.logging.Logger.getLogger(load.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnsupportedEncodingException ex) {
java.util.logging.Logger.getLogger(load.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void load() throws FileNotFoundException, UnsupportedEncodingException {
//Your display method implementation.
wordVectors = WordVectorSerializer.loadTxtVectors(new File("glove.twitter.27B.200d.txt"));
}
public double Simmiraty(String a, String b){
return wordVectors.similarity(a,b);
}
public static void main(String[] args) {
load Obj= new load ();
Obj.run();
}
}
The Second class:
public class B{
public static void main(String[] args) throws Exception {
load ob =new load();
System.out.println( ob.Simmiraty("iphone", "battery"));
}
}
I have to prolem with the above code:
1. it stops running once it has loaded the model.
2. I can't invoke any method from the frist class.
public class Load implements Runnable{
private InputStream stream;
private static final Load instance;
private WordVectors wordVectors;
static {
instance = new Load();
instance.run();
}
public static Load GetLoad(){
return instance;
}
private Load(){
if(instance != null)
throw new UnsupportedOperationException();
}
public voir run() {
if(wordVectors != null)
throw new UnsupportedOperationException();
try {
load();
} catch (Exception ex) {
Logger.getLogger(load.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void load() throws FileNotFoundException, UnsupportedEncodingException {
stream = new InputStream(new File("glove.twitter.27B.200d.txt"));
wordVectors = WordVectorSerializer.loadTxtVectors(stream,false);
}
public void interrupt(){
if(stream != null)
stream.close();
}
public double Simmiraty(String a, String b){
return wordVectors.similarity(a,b);
}
public static void main(){
Load load = GetLoad();
}
}
public class B{
public void function(){
Load load = Load.GetLoad();
}
}
public interface FileReader {
void readFile();
void writeFile();
}
public class XMLReader implements FileReader {
#Override
public void readFile() {
System.out.println("Hellp i am read");
}
#Override
public void writeFile() {
System.out.println("Hello i am write");
}
}
public class ExcelReader implements FileReader {
#Override
public void readFile() {
System.out.println("Hellp i am read");
}
#Override
public void writeFile() {
System.out.println("Hello i am write");
}
}
public class Context {
FileReader reader ;
public Context(FileReader reader) {
super();
this.reader = reader;
}
public void executeRead(){
reader.readFile();
}
}
public class TestStrategy {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(args[0]);
String s=args[0];
String[] a=s.split("\\.");
if(a[1].equals("csv")){
new Context(new XMLReader()).executeRead();
}else{
new Context(new ExcelReader()).executeRead();
}
}
}
I have a concern more file format are introduced we will create separate class for them but i have to change the if else code in TestStrategy class to create new object for the file pattern introduced.
Can we remove this if else code .Any suggestions.
You could use a registry that maps a files extension to the implementation.
public class Registry {
static Map<String,FileReader> reg = new HashMap<String,FileReader>();
public static void register(String ext, FileReader fr ) {
reg.put( ext, fr );
}
}
and let newly added implementation register themself e.g.
public class XMLReader implements FileReader {
static {
Registry.register( "xml", new XMLReader() );
}
....
public class ExcelReader implements FileReader {
static {
Registry.register( "xls", new ExcelReader() );
}
...
then you could simply lookup the registry for a suitable implementation with no if or switch required.
You can get a class by name. Build a Map to configure the FileReader to use for each extension.
public static void main(String[] args)
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Map<String, String> extensionToClass = new HashMap<>();
extensionToClass.put("xml", "de.lhorn.XMLReader");
extensionToClass.put("xls", "de.lhorn.ExcelReader");
String s = "foo.xml";
String[] a = s.split("\\.");
String extension = a[1];
// Get the class that is configured for the extension.
String className = extensionToClass.get(extension);
Class clazz = Class.forName(className);
// Create a new instance of this class.
FileReader reader = (FileReader) clazz.newInstance();
// Use the FileReader.
new Context(reader).executeRead();
}
You can read extensionToClass from an external source, of course.
Below is my CuratorClient class which is connecting to Zookeeper and starting the leader election process as well.
public class CuratorClient {
// can I make this as static?
private static CuratorFramework client;
private String latchPath;
private String id;
private LeaderLatch leaderLatch;
public CuratorClient(String connString, String latchPath, String id) {
client = CuratorFrameworkFactory.newClient(connString, new ExponentialBackoffRetry(1000, Integer.MAX_VALUE));
this.id = id;
this.latchPath = latchPath;
}
public void start() throws Exception {
client.start();
client.getCuratorClient().blockUntilConnectedOrTimedOut();
leaderLatch = new LeaderLatch(client, latchPath, id);
leaderLatch.start();
}
public boolean isLeader() {
return leaderLatch.hasLeadership();
}
public Participant currentLeader() throws Exception {
return leaderLatch.getLeader();
}
public void close() throws IOException {
leaderLatch.close();
client.close();
}
// can I use below method from any other class ?
protected static List<String> getChildren(String node) throws Exception {
return client.getChildren().forPath(node);
}
}
When my service gets started up, in the static block I am making a connection to Zookeeper using CuratorClient and starting the leader election process as well.
public class TestService {
private static CuratorClient curatorClient = null;
static {
try {
String connectionString = "some-string";
String hostname = "machineA";
curatorClient = new CuratorClient(connectionString, "/my/latch", hostname);
curatorClient.start();
} catch (Exception ex) {
// log exception
}
}
....
....
// some method
public Map<String, String> installNewSoftware(String node) {
//.. some other code
try {
List<String> children = CuratorClient.getChildren("/my/example");
System.out.println(children);
} catch (Exception e) {
e.printStackTrace();
}
//.. some other code
return null;
}
}
Now I have some other class as well which likes to use the getChildren method of CuratorClient so in this class, I can directly use like this CuratorClient.getChildren("/my/example"); correct?
public class DifferentClass {
....
....
// some new method
public Map<String, String> installNewSoftware(String node) {
try {
List<String> children = CuratorClient.getChildren("/my/example");
System.out.println(children);
} catch (Exception e) {
e.printStackTrace();
}
//.. some other code
return null;
}
}
In general, this is not a curator question or zookeeper question. It's basically a design question and I am trying to understand whether the way I am doing it will have any problem or not? And I am assuming CuratorFramework will be thread safe as well?
Yes, you can call static methods from other classes.
Your signature looks like this:
protected static List<String> getChildren(String node) throws Exception
The reason you can't call this from another class is because it's protected (visible to the current class and subclasses) instead of public (visible to everywhere).
If you make it visible you can call it with CuratorClient.getChildren().
More information on access modifiers.
More information on class members (static fields).
I'd like to change from which .properties file class should get them.
My class is like this now:
public class MyClass {
private String str;
public MyClass() throws IOException {
loadProperties();
}
private void loadProperties() throws IOException {
Properties props = new Properties();
props.load(getClass().getClassLoader().getResourceAsStream("my.properties"));
str= props.getProperty("property");
}
And whyle testing i would like properties to be loaded from another file.
It's apache camel app, so i have this now:
public class ConverterTest {
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new MyClass(); //--> Here i must load from another file
}
#Test
// test
}
Can this be achieved?
Just pass property file name to MyClass constructor
public MyClass(String propsFile) throws IOException {
loadProperties(propsFile);
}
There is something you can do:
public class MyClass {
private String str;
private String path = "my.properties";
public MyClass() throws IOException {
loadProperties();
}
protected void loadProperties() throws IOException {
Properties props = new Properties();
props.load(getClass().getClassLoader().getResourceAsStream(path));
str= props.getProperty("property");
}
And then, add a test to the same package with the code:
myClass = new MyClass();
ReflectionTestUtils.setField(path, "otherpathto.properties");
myClass.loadProperties();
It involves a small change in the code, but it might not be a big deal... depending on your project.
Arguably the cleanest solution would be to refactor MyClass and remove dependency on Properties object and inject the values needed via the constructor instead. Your case proves that hidden and hardcoded dependencies complicate testing.
Responsibility for reading the properties file and injecting the value into MyClass could be pushed back to its caller:
public class MyClass {
private final String str;
public MyClass(String strValue) {
this.str = strValue;
}
// ...
}
public class ProductionCode {
public someMethod() {
Properties props = new Properties();
props.load(getClass().getClassLoader().getResourceAsStream("my.properties"));
String str = props.getProperty("property");
MyClass obj = new MyClass(str);
obj.foo();
}
}
public class ConverterTest {
#Test
public void test() {
String testStr = "str for testing";
MyClass testee = new MyClass(testStr);
testee.foo();
// assertions
}
}
I have the following class:
class MyClass{
private static final int VERSION_VALUE = 8;
private static final String VERSION_KEY = "versionName";
public boolean myPublicMethod(String str) {
try {
return myPrivateMethod(str, VERSION_KEY, VERSION_VALUE,
new MyInnerClass() {
#Override
public InputStream loadResource(String name) {
//do something important
}
});
}
catch (Exception e) {
}
return false;
}
private boolean myPrivateMethod(String str, String key, int version,
ResourceLoader resourceLoader) throws Exception
{
//do something
}
private static abstract class MyInnerClass {
public abstract InputStream loadResource(String name);
}
}
I want to write unit test for myPrivateMethod for which I need to pass resourceLoader object and override it's loadResource method.
Here is my test method:
#Test
public void testMyPrivateMethod() throws Exception {
Class<?> cls = Class.forName("my.pack.MyClass$MyInnerClass");
Method method = cls.getDeclaredMethod("loadResource", String.class);
//create inner class instance and override method
Whitebox.invokeMethod(myClassObject, "testValue1", "testValue2", "name1", 10, innerClassObject);
}
Note, that I can't change code.
Well, you could use Javassist...
See this question. I haven't tried this, but you can call this method when you want the override:
public <T extends Object> T getOverride(Class<T> cls, MethodHandler handler) {
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(cls);
factory.setFilter(
new MethodFilter() {
#Override
public boolean isHandled(Method method) {
return Modifier.isAbstract(method.getModifiers());
}
}
);
return (T) factory.create(new Class<?>[0], new Object[0], handler);
}
Well, the problem i see with your code is that you are calling myPublicMethod and you are giving fourth parameter as new MyInnerClass(). Now in your private method fourth parameter is given as ResourceLoader and from your code i see no relation between MyInnerClass and ResourceLoader. So you can try out following code. It might help.
Despite your warning that you cannot change the code i have changed it because i was trying to run your code.
class MyClass{
private static final int VERSION_VALUE = 8;
private static final String VERSION_KEY = "versionName";
public boolean myPublicMethod(String str) {
try {
return myPrivateMethod(str, VERSION_KEY, VERSION_VALUE,
new MyInnerClass() {
#Override
public InputStream loadResource(String name) {
return null;
//do something important
}
});
}
catch (Exception e) {
}
return false;
}
private boolean myPrivateMethod(String str, String key, int version,
MyInnerClass resourceLoader) throws Exception
{
return false;
//do something
}
private static abstract class MyInnerClass {
public abstract InputStream loadResource(String name);
}
}
Hope it helps.