java.lang.IllegalArgumentException: Can not create a Path from a null string - java

**“Path inputPath = new Path(job.get(KnnDriver.QUERY_DIR_PROPERTY));”**//it gives out error。
if (inputPath == null)
throw new UnsupportedOperationException("ERROR: query directory not set");
job.setInputFormat(NonSplitableTextInputFormat.class);
NonSplitableTextInputFormat.addInputPath(job, inputPath);
Path outputPath = new Path(job.get(KnnDriver.RESULT_DIR_PROPERTY));
FileSystem.get(job).delete(outputPath, true);
// Change to FileOutputFormat to see output
job.setOutputFormat(TextOutputFormat.class);
TextOutputFormat.setOutputPath(job, outputPath);
KnnDriver.run(job);
}
I have taged the error in the text。
The following will be the static constant I have set in knnDriver.
public static final String QUERY_DIR_PROPERTY = "knn.query.dir";
public static final String RESULT_DIR_PROPERTY = "knn.result.dir";
public static final String THRESHOLD_PROPERTY = "knn.sim.threshold";

Instead of looking to see if the variable is null first, and then doing whatever you need, just do whatever you need as long as it's not null. This eliminates the need to check to see if a variable is "exactly" equal to something. It creates complications.
To avoid this, use an if statement that does what was stated above.
if(inputPath != null){
//Whatever you want
}else{
//However you want to catch it
}
Basically, you're not looking for the black swan anymore, but just checking that there aren't any. This approach is much less problematic and should be used instead of the way you did.

Related

Resolve environment variables of property file Java ResourceBundle

Our application is using java8 and spring. We are working to moving to kubernetes. For that reason, I want to use environment variables in the properties file like as follow and declare the -
conf.dir.path = ${APPLICATION_CONF_PATH}
database.name = ${APPLICATION_DB_SCHEMA}
save.file.path = ${COMMON_SAVE_PATH}${APPLICATION_SAVE_PATH}
# And many more keys
But right now the values are not resolved/expanded by environment variable.
Application initialization of property is as below -
public enum ApplicationResource {
CONF_DIR_PATH("conf.dir.path"),
DB_NAME("database.name")
FILE_SAVE_PATH("save.file.path"),
// And many more keys
private final String value;
ApplicationResource(String value) {
this.value = value;
}
private static final String BUNDLE_NAME = "ApplicationResource";
private static Properties props;
static {
try {
Properties defaults = new Properties();
initEnvironment(defaults, BUNDLE_NAME);
props = new Properties(defaults);
} catch (Throwable t) {
t.printStackTrace();
}
}
private static void initEnvironment(Properties props, String bundleName) throws Throwable {
ResourceBundle rb = ResourceBundle.getBundle(bundleName);
Enumeration<?> enu = rb.getKeys();
String key = null;
String value = null;
while (enu.hasMoreElements()) {
key = (String) enu.nextElement();
value = rb.getString(key);
props.setProperty(key, value);
}
}
public String getString() {
return props.getProperty(value);
}
public int getInt() throws NumberFormatException {
String str = getString();
if (str == null || str.length() == 0) {
return 0;
} else {
return Integer.parseInt(str);
}
}
}
getString is used extensively. Right now when getString is called, it returns the literal string from the properties file. Is there any way to properly resolve environment variables without impacting the codebase?
Edit: By [without impacting the codebase], I meant only changing/editing code in the above enum/class file and the change being transparent in other areas.
The simplest variant based on the Regex engine would be:
private static final Pattern VARIABLE = Pattern.compile("\\$\\{(.*?)\\}");
public String getString() {
return VARIABLE.matcher(props.getProperty(value))
.replaceAll(mr -> Matcher.quoteReplacement(System.getenv(mr.group(1))));
}
This replaces all occurrences of ${VAR} with the result of looking up System.getenv("VAR"). If the string contains no variable references, the original string is returned. It does, however, not handle absent variables. If you want to handle them (in a different way than failing with a runtime exception), you have to add the policy to the function.
E.g. the following code keeps variable references in their original form if the variable has not been found:
public String getString() {
return VARIABLE.matcher(props.getProperty(value))
.replaceAll(mr -> {
String envVal = System.getenv(mr.group(1));
return Matcher.quoteReplacement(envVal != null? envVal: mr.group());
});
}
replaceAll(Function<MatchResult, String>) requires Java 9 or newer. For previous versions, you’d have to implement such a replacement loop yourself. E.g.
public String getString() {
String string = props.getProperty(value);
Matcher m = VARIABLE.matcher(string);
if(!m.find()) return string;
StringBuilder sb = new StringBuilder();
int last = 0;
do {
String replacement = System.getenv(m.group(1));
if(replacement != null) {
sb.append(string, last, m.start()).append(replacement);
last = m.end();
}
} while(m.find());
return sb.append(string, last, string.length()).toString();
}
This variant does not use appendReplacement/appendTail which is normally used to build such loops, for two reasons.
First, it provides more control over how the replacement is inserted, i.e. by inserting it literally via append(replacement) we don’t need Matcher.quoteReplacement(…).
Second, we can use StringBuilder instead of StringBuffer which might also be more efficient. The Java 9 solution uses StringBuilder under the hood, as support for it has been added to appendReplacement/appendTail in this version too. But for previous versions, StringBuilder can only be used when implementing the logic manually.
Note that unlike the replaceAll variant, the case of absent variables can be handled simpler and more efficient with a manual replacement loop, as we can simply skip them.
You said you don’t want to change the initialization code, but I still recommend bringing it into a more idiomatic form, i.e.
private static void initEnvironment(Properties props, String bundleName) {
ResourceBundle rb = ResourceBundle.getBundle(bundleName);
for(Enumeration<String> enu = rb.getKeys(); enu.hasMoreElements(); ) {
String key = enu.nextElement();
String value = rb.getString(key);
props.setProperty(key, value);
}
}
In the end, it’s still doing the same. But iteration loops should be using for, to keep initialization expression, loop condition and fetching the next element as close as possible. Further, there is no reason to use Enumeration<?> with a type cast when you can use Enumeration<String> in the first place. And don’t declare variables outside the necessary scope. And there’s no reason to pre-initialize them with null.
Spring support environment variable or system variable or application.property file
if you able to use kubernates configmap its better choice.
How to set environment variable dynamically in spring test

How do I use this method? (the method takes a text file and convert it into a string)

I'm currently in a High School level Java course. I've been doing plenty of research here, on Stack Overflow, trying to work through a project i'm currently assigned. The project consists of making modifications to, and searching through, various words pulled from an encyclopedia file. This is what I am having trouble with, the very basic form of this project. I already found the method in which to solve this problem, but i wasn't able to find a good way of implementing it. This is a copy of the code i found here: (the third method down contains the portion i took from this site)
class word
{
public String newString;
EasyReader fileIn = new EasyReader("Encyclopedia.txt");
EasyWriter fileOut = new EasyWriter("writeHere.txt");
String fileName="Encyclopedia.txt";
private String onFile;
public word()
{
onFile="";
}
public word(String s)
{
onFile=s;
}
String file = "Encyclopedia.txt";
private String readFile(String file) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line=null;
StringBuilder stringBuilder = new StringBuilder();
String is=System.getProperty("line.seperator");
while((line=reader.readLine())!=null)
{
stringBuilder.append(line);
stringBuilder.append(is);
}
newString=stringBuilder.toString();
return stringBuilder.toString();
}
}
So, the question: how do i use this method? i know it sounds silly, but how do run this method and then use the data later? It is supposed to take a given text file and return a string, but i'm not even sure how to get the return value after it has processed.
Any help would be greatly appreciated. I made an account here just to ask this question. If i need to post this somewhere else, or if there is a better site to use to find an answer and some more basic help, please let me know. Thanks,
-Ethan
The readFile method seems to be doing multiple things at once. It accepts a file argument which overrides the member variable with the same name. Then it reads the file into a String and sets the newString member variable to the result before returning the same result.
So I would recommend first deciding whether the method should return the data or set the member variable. If multiple methods are going to be using the result, it might be useful to use the member variable, otherwise go the return route. Also, you can probably remove the file member variable since it is ignored by the method.
You can rewrite the method to look like this (I just removed the newString=stringBuilder.toString(); line, and I changed it to static since it can be):
private static String readFile(String file) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line=null;
StringBuilder stringBuilder = new StringBuilder();
String is=System.getProperty("line.seperator");
while((line=reader.readLine())!=null)
{
stringBuilder.append(line);
stringBuilder.append(is);
}
return stringBuilder.toString();
}
And wherever you need to use it call it like this (remember to catch the IOException):
try {
String someString = readFile("filename.txt");
} catch(IOException e) {
// handle error
}
Remember it must be called from inside the same class unless you change private to public.
Also, it might be worth reading and following a standard code style. It can really help by distinguishing between different types of variable for example.
Actual method that read string from file is: "readFile". And in your class, you are not calling that.
private String readFile(String file) throws IOException
You can pass file name as parameter, and It will returns read string.
So, how about modify your word(String s), and add method that will return actual result of read file?
public word(String s)
{
onFile=s;
newString = readfile(onFile);
}
public getNewString(){
return newString;
}
Try this:
String file ="/path/to/file.csv"
word myWord = new word();
o = myWord.getClass().getDeclaredMethod("readFile");
o.setAccessible(true);
Object r = o.invoke(myWord);
//print result

JAVA IF Else variables

public void actionPerformed(ActionEvent arg0) {
String employeeInput;
String assetInput;
String userInput = txtUserInput.getText();
userInput = userInput.toLowerCase();
if (userInput.startsWith("emp")){
//String employeeInput = null;
employeeInput = userInput.replaceAll("\\s","");
txtUserInput.setText("");
JOptionPane.showMessageDialog(frame, "The Scan was " );
}else if (userInput.startsWith("u")){
assetInput = userInput;
assetInput.replaceAll("\\s","");
txtUserInput.setText("");
System.out.println("Employee ID is " + **employeeInput**); //asks for employeeInput to be declared.
JOptionPane.showMessageDialog(frame, "The Scan was " + assetInput);
I want the employeeInput to be filled and saved, untill it is replaced by another employeeInput. The problem I'm having is when getting the item input, the employeeInput is now missing. What is the way to do this?
Thank you, for your help
employeeInput is a method variable, so everytime you exit the method you will lose the reference to it.
The obvious thing to try is turn employeeInput into a member variable. Just declare it at the top of your class.
Better yet may be to persist that value to a database.
The compiler doesn't know that the first condition has already been met. Nor, do I. But, you could change
String employeeInput; // <-- may not have been initialized
to a default value (possibly even explicitly null), here the empty String "".
String employeeInput = "";
It doesn't look like your employeeInput variable is 'missing' or could be removed after any other variable is set. So its most likely you aren't initializing your variables when they're defined.
Try initializing them like
String employeeInput = ""; // or = null
String assetInput = ""; // or = null
String userInput = txtUserInput.getText().toLowerCase();
And your problem should be solved. The compiler might also be giving you a warning about this.
You might also want to try removing this txtUserInput.setText(""); line to test for problems.
Edit:
If you are trying to access this variable after your method has finished executing then it will be wiped so instead of putting it in your method declare it in your class like public class Name{
public /*static*/ String employeeInput = ""; //or null
}

Returning the needed value in a class - Java

I am confused about returning the needed value. Here is a part of my code:
public class StrNum {
public static int getInt(String input) {
String str = new String(input);
int result;
if (str.startsWith("b")) {
str = str.substring(1);
result = Integer.parseInt(str, 2);
}
else if (str.startsWith("x")) {
str = str.substring(1);
result = Integer.parseInt(str, 16);
}
Now, what I need to return is result. When I write return result;, it asks me to initialize the variable (and I am aware that it hasn't been initialized). When I use return result inside of the if statements, Eclipse tells me that I have to return a value.
Where am I being stupid here? I would appreciate a good explanation.
What will the method getInt() return if Str doesn't start with neither "b" or "x"? That would be an error because result is not being initialized. You could solve this by intializing result with a value that you would like to return in that case:
int result = -1; // for example
Edit:
Since you want to use input to determine if the number will be parsed as binary or hexadecimal, I would recommend you to add an else statement to parse the number in base 10 as default:
if (...)
// ...
else if (...)
// ...
else
result = Integer.parseInt(Str);
Note:
Try to follow Java naming conventions. Use names like someVar for variables/methods and use names like SomeClass for classes.
It's not necessary to create a new string instance Str, unless you are going to use the original input later in the same method.
To create a String with the same content you can simply do
String str = input;
Try
int result = 0;
You must initialize variables before returning them or in other words do result = . The variable must always be initialized no matter what code path your application takes.
Your can either return the result from if and also from else, provided you are not doing additional calculations after the else block.
or simply initialize result = 0, it will change anyways before you return.

How can I know after TAB where the focus is and how to work with that component in RFT?

I work with RFT and would like to know how to get the object where the Focus is and be able to work with the object after.
For example my script starts than I write
getScreen().inputKeys("{TAB}") and
I would like to know which component has the Focus
and after this I would like to know how can I get the properties of this focused object like
.getProperty(".text"); or .getProperty(".name");
The reason I Need this is because I would like to write a testscript to test the Focus order in our Website.
Thank you in advance,
Krisz
You can do this using a simple method like
private void hasFocus(TestObject to) {
boolean hasFocus = ((Boolean)to.getProperty(".hasFocus")).booleanValue();
if (!hasFocus)
throw new RuntimeException(to.getNameInScript()+" has an invalid focus order!");
}
and calling this method after each TAB press; giving the test object expected to gain focus as the parameter. Sample script code:
browser_htmlBrowser().inputKeys("{TAB}");
hasFocus(firstObj());
browser_htmlBrowser().inputKeys("{TAB}");
hasFocus(secondObj());
I'd do a search on objects whose ".hasFocus" property is set to "true". From there, you could just run the method in a loop to check that the currently focused element is the one you want. I'd also personally recommend (if possible) to check against the ".id" property, since for a given (web)page, that's guaranteed to be a unique identifier... whereas I'm not entirely sure the ".name" property is.
public void testMain(Object[] args) {
ArrayList<String> focusOrder = new ArrayList<String>();
String currentlyFocusedObjectName = "";
// Add element names to the list
focusOrder.add("Object1");
focusOrder.add("Object2");
// ...
focusOrder.add("Objectn");
// Iterate through the list, tabbing and checking ".name" property each time
for (String s: focusOrder) {
TestObject currentObject = getCurrentlyFocusedElement();
// Tab
getScreen().inputKeys("{TAB}");
if (currentObject != null) {
currentlyFocusedObjectName = getCurrentlyFocusedElement().getProperty(".name")
.toString();
// Do other stuff with the object
}
else {
currentlyFocusedObjectName = "";
}
// Verify that the currently focused object matches the current iteration in the list.
vpManual(s + "HasFocus", currentlyFocusedObjectName, s).performTest();
}
}
private TestObject getCurrentlyFocusedElement() {
RootTestObject root = RootTestObject.getRootTestObject();
TestObject[] focusedObjects = root.find(atProperty(".hasFocus", "true");
TestObject currentlyFocusedObject = null;
// Check to ensure that an object was found
if (focusedObjects.length > 0) {
currentlyFocusedObject = focusedObjects[0];
}
else {
unregister(focusedObjects);
return null;
}
// Clean up the object
unregister(focusedObjects);
return currentlyFocusedObject;
}

Categories