I have imported an existing project into Eclipse workspace.
I have this line of code inside my existing Project.
String eod = Props.getProperty("client.eod", 5);
What is the exact meaning of the argument 5 in this call?
My guess is that if there is no property with the name client.eod whether it will set the value 5 to it. Could anybody confirm or disprove it?
Well, the docs says that the method signature is
public String getProperty(String key, String defaultValue)
hence the second argument is the default value; the docs also adds that
The method returns the default value argument if the property is not
found.
so it works as you imagined.
Yes, You are correct. But it is getProperty(String, String)
String eod = Props.getProperty("client.eod", "5");
String eod = Props.getProperty("client.eod", 5);
System.out.println("eod: "+eod);
Ya This will set the client.eod for 5.
If the value is not defined in properties file then it sets the default value.
so It gives output as below
eod:5
Related
The call of the hashCode() method on File object , triggers this SonarQube issue :
Use the original value instead.
How to resolve? Any help please?
File file = ......
.... = Math.abs(file.hashCode());
Update: the SonarQube description of the issue is here
Can I just write : .... = Math.abs(file.hashCode()+1);
The cause of your problem is the fact that Integer.MIN returns itself when taking the absolute value. This issue is described here.
The solution depends on what you need the value for. Your suggested solution (Math.abs(file.hashCode() + 1)) won't work, because if the hashCode() function returns Integer.MAX then that plus 1 is still Integer.MIN, so the final result could still be negative.
If you really need a positive hash of the file, you could do something like this:
final int hash = file.hashCode() == Integer.MIN ? Integer.MAX : Math.abs(file.hashCode());
On a windows 2012 R2 platform I noticed that winver returns 6.3, but System.getProperty("os.version") returns 6.2 ; I am looking at this source code :
class [More ...] Properties extends Hashtable<Object,Object> {
protected Properties defaults;
public String [More ...] getProperty(String key) {
Object oval = super.get(key);
String sval = (oval instanceof String) ? (String)oval : null;
return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
}
}
I am suspecting the value of os.version is obtained from here. Is my suspicion right ?
Object oval = super.get(key);
What would be the contents of the HashTable and how is this populated ? ( I have not loaded the java source code as a project into my eclipse work-bench)
The system property os.version is added by the JVM itself thanks to the static native method initProperties(Properties props) as you can see here at the line 527. This method is called while initializing the System class which is done by the method initializeSystemClass().
In other words it means that the native code of your JVM is not able to recognize your os version, you should upgrade your JDK to fix this issue.
Here is a blog post where the blogger had the same issue with an old version of Java, upgrading it was enough to fix the issue.
This problem was seen before java 6u38. From 6u38, this issue is solved. The security baselines for the Java Runtime Environment (JRE) at the time of the release of JDK 6u38 are specified.
First using the EPM Java JDK version.
As you see it is generating incorrect information, now using a later JDK 7 release.
So this highlights it is the down to the version of Java which is causing the issue.
Resource Link:
EPM 11.1.2.4 - Java versions and why Windows Server 2012 is not
correctly recognised
I am suspecting the value of os.version is obtained from Object oval =
super.get(key);. Is my suspicion right ?
Answer:
You are right. But here is some mechanism
First mechanism:
System.getProperty("os.version"); //which is called the OS version.
The getProperty method returns a string containing the value of the property. If the property does not exist, this version of getProperty returns null.
Second Mechanism:
System.getProperty("os.version", "Windows Server 2012 R2(6.3)");
getProperty requires two String arguments: the first argument is the key to look up and the second argument is a default value to return if the key cannot be found or if it has no value. For example, the following invocation of getProperty looks up the System property called os.version. This is not a valid system property, so instead of returning null, this method returns the default value provided as a second argument: "Windows Server 2012 R2(6.3)"
The last method provided by the System class to access property values is the getProperties method, which returns a Properties object. This object contains a complete set of system property definitions.
What would be the contents of the HashTable and how is this populated
?
Answer:
Properties extends java.util.Hashtable. Some of the methods inherited from Hashtable support the following actions:
testing to see if a particular key or value is in the Properties
object,
getting the current number of key/value pairs,
removing a key and its value,
adding a key/value pair to the Properties list,
enumerating over the values or the keys,
retrieving a value by its key, and
finding out if the Properties object is empty.
You can learn more from here about System Properties and Properties
Property related info is read and can be changed through this java class: PropertiesTest.java
Note and Recommendation from Oracle
Warning: Changing system properties is potentially dangerous and
should be done with discretion. Many system properties are not reread
after start-up and are there for informational purposes. Changing some
properties may have unexpected side-effects.
Note: Some of the methods described above are defined in Hashtable,
and thus accept key and value argument types other than String. Always
use Strings for keys and values, even if the method allows other
types. Also do not invoke Hashtable.set or Hastable.setAll on
Properties objects; always use Properties.setProperty.
In a PreProcessor I am writing I can successfully update GET query string via sampler.
However if I use the same approach with POST, while I can list the FORM fields via getArguments(), the value does not get set.
Arguments arguments = sampler.getArguments();
for (int i=0; i<arguments.getArgumentCount(); i++) {
Argument argument = arguments.getArgument(i);
if (argument.getName().equals("page_submission_id")) {
String newVal = "8743718386872";
argument.setValue(newVal);
System.out.println("Setting arg["+argument.getName()+"] to["+newVal+"]");
}
}
sampler.setArguments(arguments);
printArgs(arguments);
The output from this shows Arguments values are unchanged.
Setting arg[page_submission_id] to[8743718386872]
Arguments After
...
Found arg[page_submission_id] is[XXXXXXXXXXXXX]
...
Having dug into the jmeter code a bit further, there is a "runningVersion" attribute of an Attribute object which (via isRunningVersion()) is set true.
I have tried a few ways to get round this:
force runningVersion to false - then values are set but a GET message is sent
create a new Arguments object and add new Argument entries to it with values - this does not change the values
Can anyone point out the official way to set POST FORM field values before they get sent?
Thanks
Well, you assigning a new value to an argument, but I fail to see where you updating sampler's arguments with the argument having the new value.
I'm a strong believer of KISS principle so instead of adding some more lines I would recommend simplifying your script as follows:
import org.apache.jmeter.config.Argument;
sampler.getArguments().removeArgument("page_submission_id");
sampler.addArgument("page_submission_id","8743718386872");
Also I hope you're using JSR223 PreProcessor and Groovy language.
I managed to resolve this:
(initially) by cleaning up the Thread Pool, as my initial
attempts had included a number of things like "Regular Expression
Extractors" and "User defined variables". Once those were removed
the approach I was using successfully changed the argument values, and
(when deeper in to my setup the problem came back) by adding the creation of a new Argments object and inserting (in the same order) new Argument objects with the value set as I require. Then setting the sampler to use that new Arguments object.
Arguments newArgs = new Arguments();
Arguments arguments = sampler.getArguments();
for (int i=0; i<arguments.getArgumentCount(); i++) {
Argument argument = arguments.getArgument(i);
HTTPArgument newArg = new HTTPArgument();
newArg.setName(arguments.getName());
if (arguments.getName().equals("field_to_replace")) {
newArg.setValue("new value");
}
else {
newArg.setValue(arguments.getValue());
}
newArgs.addArgument(newArg);
}
sampler.setArguments(newArgs);
My take is that this down to the "if (isRunningVersion())" test within setProperty() used by "Argument.setValue()" which I'm tripping over.
While this appears to work (for my test cases so far) I appreciate that overriding this may not be the correct formal approach.
How to convert String to By type.
Following is my scenario:
Keep object identification in Properties file in below manner
username=By.id("username")
password=By.id("password")
In the application i would like to retrieve the values like
Properties prop=new Properties();
prop.load("above properties file path")
driver.findelement(prop.getProperty("username")) //Here in eclipse it is complaining saying "The method findElement(By) in the type WebDriver is not applicable for the arguments (String)"
So can somebody help me in this?
I can use like below or some other format, but i want solution for the above
username="//*[#id='username']"
username="username"
driver.findElement(By.xpath(prop.getProperty("username"))
driver.findElement(By.id(prop.getProperty("username"))
You can create one parser method which will return desired locator object something like below:
public static By locatorParser(String locator) {
By loc = By.id(locator);
if (locator.contains("id"))
loc = By.id(locator.substring(locator.indexOf("\"") + 1,
locator.length() - 2));
else if (locator.contains("name"))
loc = By.name(locator.substring(locator.indexOf("\"") + 1,
locator.length() - 2));
if (locator.contains("xpath"))
loc = By.xpath(locator.substring(locator.indexOf("\"") + 1,
locator.length() - 2));
return loc;
}
Can be called in your code in the following way:
driver.findElement(locatorParser(prop.getProperty("username")));
Added logic for id, name, xpath. You can modify the same method to add all the available locators. Hope this helps!
The WebDriver.findElement method accepts only an object parameter of the type By.
The Property.getProperty method returns only a String typed object.
Therefore, this may be what fits your need:
WebElement element = driver.findElement(By.name(prop.getProperty("username")));
You can't force a String typed object into a method that accepts only a By typed object. When you ask Selenium to find a String "username" you have to tell it more than just the string's value.
The method By.[method] you choose all depends on what you are looking for in the page that Selenium is searching. "username" is most likely the "name" (By.name) or "id" (By.Id) of the field you are looking for. The By class refines the search to where you expect the String "username" to be: in a name, id, tag, class, etc. See the By class definition.
Also, take caution as the getProperty method could return a null, and the By methods with throw an IllegalArgumentException if you pass it a null string. So providing a default return value ("") for getProperty is usually safer.
WebElement element = driver.findElement(By.name(prop.getProperty("username", "")));
You have to evaluate the entire expression within the context of existing code. You should framework such as JEXL or expressionoasis
Code below uses JEXL
// Create JexlEngine instance
JexlEngine jexl = new JexlEngine();
// Create Expression object for the string
Expression e = jexl.createExpression(prop.getProperty("username"));
// Create a context. You can pass reference to any object you want to use inside the expression
JexlContext jc = new MapContext();
// Now evaluate the expression, getting the result
driver.findElement((By)e.evaluate(jc));
I think you are trying to implement page object model using properties file. What I would suggest here to use xml file instead of java properties file. for example sample xml for page elements would look like below.
<Pages>
<LoginPage>
<txtUserName by="id">username</txtUserName>
<txtPassword by="id">password</txtPassword>
</LoginPage>
</Pages>
Now you can write methods retrieve nodes from the xml file and node attribute as id,xpath etc... further write methods to find elements using xml node value and attribute. I have used same method in my project as it works great for me.
The situation seems to be abnormal, but I was asked to build serializer that will parse an object into string by concatenating results of "get" methods. The values should appear in the same order as their "get" equivalent is declared in source code file.
So, for example, we have
Class testBean1{
public String getValue1(){
return "value1";
}
public String getValue2(){
return "value2";
}
}
The result should be:
"value1 - value2"
An not
"value2 - value1"
It can't be done with Class object according to the documentation. But I wonder if I can find this information in "*.class" file or is it lost? If such data exists, maybe, someone knows a ready to use tool for that purpose? If such information can't be found, please, suggest the most professional way of achieving the goal. I thought about adding some kind of custom annotations to the getters of the class that should be serialized.
If you want that you have to parse the source code, not the byte code.
There are a number of libraries that parse a source file into a node tree, my favorite is the javaparser (hosted at code.google.com), which, in a slightly modified version, is also used by spring roo.
On the usage page you can find some samples. Basically you will want to use a Visitor that listens for MethodDefinitions.
Although reflection does not anymore (as of java 7 I think) give you the methods in the order in which they appear in the source code, the class file appears to still (as of Java 8) contain the methods in the order in which they appear in the source code.
So, you can parse the class file looking for method names and then sort the methods based on the file offset in which each method was found.
If you want to do it in a less hacky way you can use Javassist, which will give you the line number of each declared method, so you can sort methods by line number.
I don't think the information is retained.
JAXB, for example, has #XmlType(propOrder="field1, field2") where you define the order of the fields when they are serialized to xml. You can implemenet something similar
Edit: This works only on concrete classes (the class to inspect has its own .class file). I changed the code below to reflect this. Until diving deeper into the ClassFileAnalyzer library to work with classes directly instead of reading them from a temporary file this limitation exists.
Following approach works for me:
Download and import following libarary ClassFileAnalyzer
Add the following two static methods (Attention! getClussDump() needs a little modification for writing out the class file to a temporary file: I removed my code here because it's very special at this point):
public static String getClassDump(Class<?> c) throws Exception {
String classFileName = c.getSimpleName() + ".class";
URL resource = c.getResource(classFileName);
if (resource == null) {
throw new RuntimeException("Works only for concreate classes!");
}
String absolutePath = ...; // write to temp file and get absolute path
ClassFile classFile = new ClassFile(absolutePath);
classFile.parse();
Info infos = new Info(classFile, absolutePath);
StringBuffer infoBuffer = infos.getInfos();
return infoBuffer.toString();
}
public static <S extends List<Method>> S sortMethodsBySourceOrder(Class<?> c, S methods) throws Exception {
String classDump = getClassDump(c);
int index = classDump.indexOf("constant_pool_count:");
final String dump = classDump.substring(index);
Collections.sort(methods, new Comparator<Method>() {
public int compare(Method o1, Method o2) {
Integer i1 = Integer.valueOf(dump.indexOf(" " + o1.getName() + lineSeparator));
Integer i2 = Integer.valueOf(dump.indexOf(" " + o2.getName() + lineSeparator));
return i1.compareTo(i2);
}});
return methods;
}
Now you can call the sortMethodsBySourceOrder with any List of methods (because sorting arrays is not very comfortable) and you will get the list back sorted.
It works by looking at the class dumps constant pool which in turn can be determined by the library.
Greetz,
GHad
Write your custom annotation to store ordering data, then use Method.getAnnotation(Class annotationClass)