Hi I have been struggling to get the 'getenv' to work. it will keep on returning "Exception in thread "main" java.lang.UnsupportedOperationException". I have been reading about the ProcessBuilder but i am not quite sure on how and where to implement it based on my code below.
What I want to exactly do is, to set a variable ("REGRESSION_STATUS", "UPDATED") and ("REGRESSION_STATUS", "OUTDATED") when the condition is met, and return the value "UPDATED" and "OUTDATED" as appropriate when executed through the cmd in Windows.
public static void main(String[] args) throws ClassNotFoundException {
String run_type = args[0];
String inputFile = args[1];
System.out.println("RUN TYPE = " + run_type);
System.out.println("INPUT FILE = " + inputFile);
MiniData data = getValue(run_type, "LEM");
if(run_type.equals("BUILD")){
System.out.println("Script = " + data.getScript());
}
else if (run_type.equals("DEPLOY")){
System.out.println("Script = " + data.getScript());
}
else if (run_type.equals("REGRESSION")){
System.out.println("Runtime Version (DB) = " + data.getRuntime());
String file_name =inputFile;
if(data.getRuntime().equals(getRuntimeVersion(file_name)))
{
System.out.println("The version is up-to-date");
System.getenv().put("REGRESSION_STATUS", "UPDATED");
System.getenv().put("REGRESSION_VER", data.getRuntime());
}
else
{
System.out.println("This version is outdated");
System.getenv().put("REGRESSION_STATUS", "OUTDATED");
System.getenv().put("REGRESSION_VER", data.getRuntime() );
}
}
else {
System.out.println("You have not the correct value. Enter either BUILD/DEPLOY/REGRESSION");
}
}
Thanks!
The System.getenv() method returns an unmodifiable view of the environment variables. You cannot use it to set environment variables like you're doing here.
The only time you can "set" environment variables is when you are creating an environment for a child process, using the ProcessBuilder class or the Runtime.exec method, but even then you are not modifying your copy of the environment.
You must use C putenv and JNI, there is no way to do that from Java.
Related
I am currently trying to making a custom rules plugin (for minecraft) and I am trying to see if the player has something activated which I stored in the config file. It is in the listener class (which calls the config from the main). Here is my code:
#EventHandler
public void onEvent(AsyncPlayerChatEvent e) {
Player player = e.getPlayer();
if (config.getInt("EditingLine." + player.getName().toLowerCase()) == 1) {
int line = 0;
try {
line = Integer.parseInt(e.getMessage());
} catch (Exception b) {
player.sendMessage(ChatColor.RED + "Invalid Number.");
config.set("EditingLine." + player.getName().toLowerCase(), 0);
}
if (!(line == 0)) {
config.set("EditingLine." + player.getName().toLowerCase(), 0);
config.set("EditingText." + player.getName().toLowerCase(), 1);
e.setCancelled(true);
player.sendMessage(ChatColor.GRAY + "[" + ChatColor.GOLD + "Custom Rules" + ChatColor.GRAY + "]" + ChatColor.GREEN + " Enter the text you would now like on that line.");
}
}
}
The, config.getInt() function in the if then statement currently returns nothing. This may be happening because the config in the Listener Class is actually calling a custom made config, called 'playerdata.yml' and not the actual 'config.yml'. If there is any easier way to write this script, also let me know. I'm trying to make this as simple as I can.
The answer has been solved by merging my two configuration files together.
I have a logging function in CSharp and Java that I use in walking the stack. How do I make each log print to a new line only. Below are my Java and CSharp Functions.
public static void LogFunctionCall(String parameters){
Object trace = Thread.currentThread().getStackTrace()[3];
android.util.Log.i("##################" + trace.toString()+ "", parameters );
}
the java version is this
public static void LogFunctionCall(string parameters,
[System.Runtime.CompilerServices.CallerMemberName] string methodName = "",
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
var stackFrame = new StackFrame(1);
var callerMethod = stackFrame.GetMethod();
var className = callerMethod.DeclaringType;
System.Diagnostics.Trace.WriteLine("CCCCCCCCCCCCCCCC" + " " + className + " " + methodName + " " + sourceLineNumber + " " + parameters + "\n");
}
I code on a windows machine.
Please where exactly do I need to place the new line character. I tried this
public static void LogFunctionCall(String parameters){
Object trace = Thread.currentThread().getStackTrace()[3];
android.util.Log.i("##################" + trace.toString()+ "", parameters + "\n" );
}
but I still saw some of the logs being clumped up on a single line.
Instead of \n, try \r\n (carriage return and newline). Some text editors will display differently, so the newline may be in there, but whatever app you're using to read the logs might not be displaying it correctly.
You could also try
System.lineSeparator();
I've seen instances where the /n won't work but the lineSep does.
Also, because it hasn't been mentioned, Environment.NewLine will give you the new line character that is configured for the current environment.
I am reading multiple arguments from command line using Java 1.5 . The arguments are names of flat files. I loop thru the arguments in the main method and call a method which in turn creates a bunch of threads to process the file. I need to pause the loop till all threads processing the first argument complete and then move on to create threads for the second argument. How can I queue the arguments or pause the loop execution in my main method till all threads processing current argument complete?
Use Threadpools and an Executor. Take a look at the java.util.concurrent package.
for(String argument:args){
//you said you want multiple threads to work on a single argument.
//create callables instead and use a ThreadPool
List<Callable<YourResult>> lstCallables = createCallablesFor(argument);
List<Future<YourResult>> futures = Executors.newCachedThreadPool().invokeAll(lstCallables);
for(Future<YourResult> future:futures){
//this get() waits until the thread behind the current future is done.
// it also returns whatever your callable might return.
future.get();
}
// at this point, all the threads working on the current argument are finished
// and the next loop iteration works on the next argument
}
I wonder if you are looking for something like cyclic barriers.
You need to start the thread job inside the loop for one argument so that after one job is finished next loop is started and next thread job for next argument is started. And further you can work in your thread job where you defined that.
Example: this is just a snippet
for (int i = 0; i < count; i++) {
t[i] = new RunDemo();
String[] serverList = srv[i].split(",");
String logName = filename + "_" + serverList[0] + "_log";
String sql = "INSERT INTO .....(any query)";
t[i].setStr("sqlplus -L " + username[i] + "/" + password[i] + "#"
+ serverList[1] + ":" + serverList[2] + "/" + serverList[3]
+ " #" + filename1);
t[i].setLogName(logName);
t[i].setDirectory(dir);
try{
conn.UpdateQuery(sql);
log.info("Inserted into the table data with query " + sql);
}
catch (Exception e){
log.info("The data can't be inserted into table with " + e.getMessage() + " sql query " + sql);
}
new Thread(t[i]).start();
}
Here in every loop new thread with different serverList is created and started.
Now the job definition is given below:
public void run() {
JShell jshell = new JShell();
try {
log.info("Command is: " + this.str + " log name: " + this.LogName + " in directory: " + this.directory);
jshell.executeCommand(this.str, this.LogName, this.directory);
log.info("Executed command successfully");
} catch (Exception e1) {
log.info("Error at executing command with error stack: ");
e1.printStackTrace();
}
DBConnection conn1 = new DBConnection();
String sql = "UPDATE patcheventlog SET ENDTIME=SYSDATE WHERE LOGFILE='" + this.directory + this.LogName + "'";
try {
//conn1.callConnection("192.168.8.81", "d2he");
conn1.callConnection(ip, sid);
conn1.UpdateQuery(sql);
conn1.disposeConnection();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.print(this.LogName);
}
So this is how you work with the threads inside the loop. You don't need to pause your loop.
Hope that helps.
I have written following code snippet:-
public Collection<?> constructResponse (...........) throws RemoteException {
while (keyIterator.hasNext())
{
String keyValue = (String) keyIterator.next();
keyString = new StringBuilder(); // since multiple keys will be there in map need to ensure every time keyString and valueString is created
valueString = new StringBuilder();
keyString.append(keyValue + ";" + "name");
List<CustomValuePOJO> customPOJOlist = employeeValuesMap.get(keyValue );
for (CustomValuePOJO customPOJO : customPOJOlist )
{
if (protocol == null || protocol.equals(""))
{
valueString.append(rpNatPOJO.getDcnPort() + ":"+ rpNatPOJO.getProtocol() + ";");
}
else if (customPOJO .getProtocol().equals(protocol))
{
valueString.append(customPOJO .getPort() + ":"+ protocol + ";");
}
else
{ throw new RemoteException("Invalid Argument: Unsupported protocol "+ protocol);
}
}
if (valueString.length() == 0)
{
return generateErrorResponse("No info found");
}
responseMap.put(keyString.toString(), valueString.toString());
}
}
The weird behavior which is happening is that while iterating through the customPOJO its coming inside elseIf and also setting the value in valueString by executing below code:
else if (customPOJO .getProtocol().equals(protocol))
{
valueString.append(customPOJO .getPort() + ":"+ protocol + ";");
}
After this elseif its coming directly on line
throw new RemoteException("Invalid Argument: Unsupported protocol "+ protocol);
There is no error which is coming in append operation and checked in debug perspective the value is getting appended successfully in valueString.
Please tell what i am missing
Figure I should put this as an answer instead of just a comment...
This sort of behavior can occur when your code (what you are stepping through in the debugger) is out of sync with the compiled class files (that are actually running). Since debug information is associated with line numbers, the lines may be different in the class files than in the source code you see.
Try running a clean build and make sure that there are no duplicate jars on your classpath that may be causing this.
Basically I want to be able to do be able to parse a JavaScript-like syntax. For example:
var results = system.function('example');
if(results == "hello") {
console_print("ding dong.");
}
So basically you get it, results will be a "string" and system.function will call a Java method, and those results will go into the results string.
I want to be able to do basic math, and validation in this as well, but I want this done in Java. Any ideas?
If you're willing to use JavaScript (not just JavaScript-like), and you're using Java 1.6+, then you can use the Scripting API:
import javax.script.*;
public class Main {
public static void main (String[] args) throws Exception {
String source =
"var system = new Array(); \n" +
"system['foo'] = function(s) { return 'hello'; } \n" +
" \n" +
"var results = system.foo('example'); \n" +
" \n" +
"if(results == \"hello\") { \n" +
" print(\"ding dong.\"); \n" +
"} \n";
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.eval(source);
}
}
which will print:
ding dong.
to the console.
And to invoke Java methods from the scripting language, you could give BeanShell a try:
package test;
import bsh.Interpreter;
public class Main {
public static void foo(Object param) {
System.out.println("From Java, param=" + param);
}
public static void main (String[] args) throws Exception {
Interpreter i = new Interpreter();
i.eval("a = 3 * 5; test.Main.foo(a);");
}
}
which will print:
From Java, param=15
The core interpreter JAR of BeanShell is only 143 KB: more lightweight than that will be difficult, IMO.
I think you can use Rhino for this. Rhino is an javascript engine that can be embedded in java.