Passing Shell Context Variables to Compiled Language (Java/C/C++) in Posix - java

This is a pretty simple question, but I haven't been able to find an answer to it.
I am running a shell script, and within the scope of that shell script I have defined some variables. I want to somehow access those variables from within a program run from within the shell script's context. For example, if I run a script that looks like
#!/bin/sh
VARIABLE_NAME="somevalue";
java Main;
./compiled-c-or-cpp.out
how might I access "$VARIABLE_NAME" from within Main or the compiled C/C++? Honestly I wouldn't be surprised if it's impossible but I figure this is a question worth asking.
I don't think I can use environment variables for this. I am aware of how to access environment variables through Java's System.getEnv("VARIABLE_NAME") method and C's getenv("VARIABLE_NAME") method. However the procedure I end up implementing will be used in a very multithreaded application. I need to be able to use context variables so that I can have multiple threads accessing their own "$VARIABLE_NAME" simultaneously, instead of export-ing environment variables to the whole shell.
That said, I admittedly don't have a complete understanding of the scope of environment variables. For example if each call to Runtime.getRuntime().exec("./script.sh") (for Java) or system("./script.sh") (for C/C++) is assigned its own shell, and if I am able to export environment variables to only that temporary shell, then that would be a tolerable solution.
Thanks to anyone for any help :)

You can export an environment variable to just one process, without having it in your shell:
VARIABLE_NAME="somevalue" java Main
In your case, it would more likely be like this
VARIABLE_NAME="somevalue" (java Main; ./compiled-c-or-cpp.out)

Related

How to read "OS variables" from Java (not System.properties)

I just read the excellent 12 Factor App document and it really registered with me. In Chapter 3 Config, the author stresses that:
The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.
I'm wondering what this implies for Java projects.
Typically, when it comes to my Java apps, I think of "env vars" as things that I can read from System.getProperty("blah"). Is this what the author is talking about? I don't think this is, because the author explicitly states "and unlike...or other config mechanisms such as Java System Properties...".
If not, what would be an example of an OS-agnostic "env var" that would satisfy this document's definition of "env var"? How would I read it from inside Java code?
Either way, some process has to first set each env var on the OS, so that the var is set & available by the time the app runs. What processes/methods could do this type of pre-run setup?
Use System.getenv() instead of System.getProperty(). System.getenv() returns value of specified environment variable defined in your OS.
Other, and probably preferable way is to pass selected OS environment variable to your JVM using -D command switch and then retrieve them using System.getProperty(). This way is more cross-platform: you may use the same java code even if specific platform does not support specific variable.
Updating the OS variables is absolutely other task. First, I do not think that you really want to do this. If you still want try to ask another question: probably other solution exists.
There is no cross platform API that does this in JDK and I do not know 3rd party library that dies this too. I personally planned to implement one but did not have time for this so far.
Windows stores variables in registry, so you can add variable to registry. But this does not affect current instance of shell, so your own java process will not see variables that it updated itself. You can however create process and run SET myvar=myvalue. If you want to write to registry you can use any of available libraries. Occasionally I implemented such library too. Its advantage is that it does not run any native code and is very compact. Take a look here.
On Unix you can run myvar=myvalue and if you want other processes to see this variable you have to run export myvar. But it still does not make this variable persisted. If you want this variable to survive OS restart you have to add it to one of the initial scripts (e.g. .bashrc). But this is completely depends on your system, configuration, permissions, shell etc.
Yes, the author is talking about environment variables. You can read environment variables from java code using the following snippet:
System.getenv(env);
See: http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getenv-java.lang.String-
If you want OS agnostic way, you can use JVM arguments and read using
System.getProperties();
For example, if you want a variable called var1 to be passed, use java -Dvar1=true -jar myJar.jar

is it possible to make Rhino keep a variable for a javascript method

The context is the following : I must write a javascript method that will be executed by a java application using Rhino. I cannot make any changes to the java application.
Then the question is:
Would it be possible to ask Rhino to save "something" in its execution context and make it available to the javascript method for next executions of this javascript method ?
and then, if yes, could this "something" be an instance of a class created on the fly by the javascript method because the java application does not contain any class that could fulfill my needs.
The short answer is no. Rhino doesn't have any global variables that you can use.
You will have to change the code of the Java application and add a new global variable to the execution context of Rhino. The Java code then needs to remember the value of the variable somewhere when the script is finished and put it again into the context when the scripts should run again.

Set default memory limit for all applets

Short version
How do I configure the icedtea-plugin package for ubuntu precise in such a way that it executes all applets with a specific memory limit by default? Preferrably using command line tools and no graphical user interface.
Long version
I'm building a kiosk setup using java applets, and would like to increase the default memory limit for all these applets. The kiosk is based on ubuntu linux, using the icedtea-plugin package as a browser plugin. As building the kiosk is automated and headless, I'd rather configure it from the command line if possible.
Here is what I've found out so far:
I'll probably have to specify a -Xmx… command line argument which will be used when starting the java virtual machine for the plugin.
It is possible to pass such arguments using a parameter in the HTML code, i.e.
<param name="java_arguments" value="-Xmx…">.
But that would mean modifying all my HTML files, which I'd rather avoid. And there is a good chance that I'd have to sign my code to make this work, which adds quite a lot of problems in other places of my project.
On my desktop system, using the Oracle VM, there is an application ControlPanel which I can use to set these command line switches. It seems that the configuration gets written to a file ~/.java/deployment/deployment.properties, where it is associated with the key deployment.javaws.jre.0.args.
That key name is not described in the specs for that file. The number 0 seems to refer to one specific JVM, as represented in one row of the table in the control panel. For each JVM, there are several values besides this args value, all sharing a common index number.
According to this wiki section, IcedTea supports a similar file, located at ~/.icedtea/. Not sure whether that means ~/.icedtea/deployment.properties or rather ~/.icedtea/deployment/deployment.properties. IcedTea does not seem to come with a ControlPanel.
As you can see, there are many hints as to how this might work, but so far I haven't seen any definite answer as to what will work. There are still many open questions:
Do I have to create this icedtea deployment file?
Do I have to include a directory named deployment in the path?
Which is the minimal set of keys that I need to specify to make this file work as intended?
Is the args value even supported by OpenJDK, even if it is not described in the corresponding specification?
I guess I could try out all possible combinations to see whether one of them works, but doing so will take considerable time. So I'm asking here, to see if someone has experience in this, and can provide a quiecker answer. If not, I guess I'll answer my own question eventually, once I've tried things the hard way.
as oracle says: http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/plugin.html.
following environment variable should be set to add additional arguments to applets:
_JPI_VM_OPTIONS=-Xmx…
Moreover as the reffered site says:
Please note that you need to restart your browser after you set the environment variable. If you are setting this environment variable in the command shell, then you must use the same command shell to launch the browser so that the browser inherits the value of environment variable.
However if you doubt how to set environment variable in ubuntu, following post might be helpful: Make $JAVA_HOME easily changable in Ubuntu
I just had a look at the source code of the icedtea-web plugin. The part of the code which builds the command line seems to have no provision at all for including custom arguments, no matter their origin. So it does not matter which config files, HTML files or environment variables I edit, the code there will build the same command line to call java, disregarding all my whishes.
So if all configuration fails, what remains is hackery. One approach would be to patch the source code of the plugin, and make it include additional words into its command line. For a static addition, i.e. a single size change, this would be fairly easy. A more general fix would include the content of some environment variable, the way Peter's answer suggests. That would mean word-splitting the environment variable in question, and allocating the space for the array of words dynamically. Quite a bit of work at the C level.
As an alternative, one could tackle this at the level of the executed binary. The plugin apparently has the path of the executable hard-coded into it. In my case, this path is /usr/lib/jvm/java-6-openjdk-amd64/jre/bin/java. One can rename that binary to java.orig, and put a shell script in its place, with the following content:
#!/bin/bash
for i in "$#"; do
if [[ "${i}" == sun.applet.PluginMain ]]; then
exec "$0.orig" -Xmx512m "$#"
fi
done
exec "$0.orig" "$#"
One consequence of this approach is the fact that ps will no longer print these applets as java but instead as java.orig. Should not be a problem in most cases.

Create an environment variable programmatically

I have an external program that I'm running.
for some reason, the code owner didn't give me the code or and good documentation, I know how to run this code but it was written originaly to be executed from command line and not from JAVA.
the effect on me is that this application uses an ENV variable and relay on its value (a path on the computer for the output).
I want to change that value, how can it be done without running it from a batch file?
I assume you are executing this program using one of the Runtime.exec() methods in Java code to create a Process.
Note that some of those methods allows you to pass environment variables to the process you are creating, for example exec(String[] cmd, String[] envp).
Alternatively, the Map returned by ProcessBuilder.environment() can be manipulated for the same effect.
how can it be done without running it from a batch file
Just set global environment variable. All new processes will see it (excluding those inheriting environment from old parent process).
See also How do I set environment variables from Java?.
This answers the question's title. Which doesn't match the question's body, btw. ;)
See this post. It usually helps to first start a search here before posting a question. If you already tried that solution, it really helps the Helpers to let them know that you tried it and what went wrong.
In your command prompt first set the required variable
set FILELOCATION=<PATH TO FILE>
java MyProgram
In this case the FILELOCATION will be available till you close the program.
Not setting variable will be dependent on OS.
For Linux or Solaris you can do :
export FILELOCATION=<PATH TO FILE>
In case you are looking for command line parameters then you can use something like this:
java MyProgram PathToFile
There is a better way of doing this java -DFILELOCATION=<PATH_TO_FILE> MyProgram
Edit: As per comment.
Just use ProcessBuilder to set ENV variable in Java code.

Running SET command using Java

I am executing an application using Java application (Runtime.get...) but now before running the application I have to set temp path.
set tmpdir=%temp%
Is it anyway I can execute above command using Java?
Running set in a separate Runtime.exec() invocation wouldn't help at all: it only ever affects the process that it runs in and each exec() call produces its own process.
What you need to do instead is provide the environment variable to your Runtime.exec() call using this two or three argument variant.
Better yet, scrap Runtime.exec() and use ProcessBuilder instead. With this you can simply use environment().put("tmpdir", "somevalue") to set the environment variable you want (you can even get the value of %temp% from that Map).
Could you execute a .cmd/.bat file rather than the app directly?

Categories

Resources