Well I know it is a stupid question, but lets think on it for a second.
Why can't we have a repl mode or kind of a shell for Java. Say I just want to do Math.max(2,3) to get output 3. It can be similar to Scala repl mode, where by default the class and main declarations are handled (it extends to App) and only an expression is evaluated.
Technically:
There is an interpreter running behind can execute it - If scala and groovy can, then that means the JVM is not the major issue
If javac is the reason, say we remove all optimizations and it directly converts line by line strictly to java byte code, then there should be a way out. Type Inference might not be strong to show a lot of information, but atleast the output of methods can be shown. Probably javac can be a bit modified for such cases
Ex: In the debugger, we attach break points to the line and then execute forward. A similar strategy can be applied
It would be cool to have a default shell for each JVM process, where on the run, one can access or set some say static variables and have live information.
All this would have been thought off, but why hasn't it been accepted by majority (there are some open source implementations though)
This is more or less exactly what BeanShell does.
The Display view in Eclipse provides a lot of convenient behaviour in this area, with command completion, access to the running application stack, and console output through System.out.
Like #Sean suggested you can indeed use bean shell in repl mode.
java -cp ./bsh-2.0b4.jar bsh.Interpreter
BeanShell 2.0b4 - by Pat Niemeyer (pat#pat.net)
bsh % System.out.println("Hello World");
Hello World
Alternatively, the less known Display tab on the eclipse IDE can execute arbitrary java code and evaluate expressions on the fly. Ctrl+U runs the expression and Ctrl+Shift+I evaluates them. It is not repl mode, but comes close.
You could try http://www.javarepl.com/ or console version from https://github.com/albertlatacz/java-repl
Related
I have situation where I start JDK18 jvm from c++ code to produce vst plugin goal being to implement audio signal algorithms in java side with added value of full java GUI api. My framework works very smoothly apart from the repeatable state where my audio streaming crashes after 14 hours. So I thought this is good place to start learning JFR. My jvm starting parameters are in xml file and relevant part is:
<param>
-XX:StartFlightRecording,dumponexit=true,filename=c:/out/blackbox.jfr
</param>
Even when application exits that named file keeps empty. So what is the idea of filename parameter if it stays empty and how to use it?
The recording is dumped in a Java shutdown hook. If you terminate the C++ application with exit(status), the Java hook never gets a chance to run.
Not sure how to best run the shutdown hooks, but you could perhaps invoke System.exit(status) from native using CallStaticVoidMethod?
My solution with JDK 18 and flight recorder is not to use JVM startup options at all but instead use jcmd's JFR commands. This is due to incompatible JVM options at startup and lacking documentation. Available documentation is clearly for some older versions of JVM. Here is the available documentation:https://docs.oracle.com/javacomponents/jmc-5-5/jfr-command-reference/toc.htm which proposes use of -XX:+UnlockCommercialFeatures which has been long gone. What is current state of command line options is not achieveable for average programmer.
But "jcmd JFR.start" is example of things that work. I got things working observing with "jcmd PID JFR.check" . It is obvious that JFR api is also little bit broken and needs to addressed in a certain way to get the wanted results. There must have been very hurry when implementing it because the order of parameters is very crucial. And there is a nag that "name" must not be a number even it uses it as number. Now I know it is sensitive. So the way I want it to function is to sample and dump periodic chunks so that differences reveal them selves. Now I have the solution to that but it needs another question with no stupid complaints. Baseline is that jcmd with JFR parameter must be used as it comes out of the box in the way which is not obvious.
I would like to modify/set JVM flags as soon as my program starts. I cannot do it on the command line, because I work with people who don't even know that exists. So it has to be automatically done in the program.
I am particularly interested by these three flags: -Xms4G -Xmx8G -noverify
I found in this discussion (or that one) that it is possible to modify some flags using the Interface HotSpotDiagnosticMXBean. And this code shows how to modify the flags. Unfortunately, the flags Xms or just ms are not recognized and then an exception is thrown.
I've also found that capsule may do the work, but it seems pretty heavy to use.
Is there any easy way to do it?
You need to write two programs: one that is just a launcher to provide the correct parameters to run your other program. This is how Eclipse works, and Jitsi, and the now-end-of-life InstallShield Multiplatform launchers. It may be that you can write a trivial (eg one line or close to it) shell, .bat, or VBS script to do the job.
I just wonder how can I get rid of the java jre dependency and produce native code and deliver the compiled code as the application?
So does it possible?
P.S. I know about gcj compiler is it what its doing ?
The compiled byte code will still depend on the java virtual machine. A JIT can't create code that "makes any sense" outside the JVM container. Yes, the result is a bunch of valid instructions for the target platform. But you still need the actual stack, heap and garbage collector (just to name a few required building blocks).
Excelsior has a very good Java2Native compiler. I would love to use it, but sadly our project takes 8 hours to compile with this compiler. The resulting speed of the app is impressive thought.
In theory, it's possible to take any interpreter for a language and turn it into a compiler that produces native code in that language. This is related to a series of equations called the Futamura projections. The high-level idea is essentially to "cheat" at how you define a compiler. Suppose that for some language L I have an interpreter I(p) that, given a program p written in language L, interprets that program. Now, I assume that interpreter I is represented directly in machine code. Further suppose that I have a program called mix that, given a machine code program and a sequence of input to that program, produces a new machine code program that is the initial program with its input fixed to be the specified input. For example, if I compiled this C++ program:
#include <iostream>
using namespace std;
int main() {
string message;
cin >> message;
cout << message << endl;
}
And then used mix to mix the program with the input "Hello," I'd get a program that always prints out the message "Hello". In other words, it would be as if I had written this program:
#include <iostream>
using namespace std;
int main() {
cout << "Hello" << endl;
}
It turns out that it's possible to build this program. I could do this, for example, by looking at the machine code, looking at every place that you try to read input from the console, and then replacing that with code that calls a function to instead read from a hardcoded string.
Now, consider what would happen if you were to run this mix program taking as input an interpreter I and some program p. Then the result of this would be a machine code program that is equivalent to the program I running on input p. In other words, you've just constructed a machine-code program that simulates what would happen if you were to run the interpreter on the program - which is a machine-code program that executes the program p!
Of course, this construction is completely impractical. To the best of my knowledge no one has written mix, and if they did, any program you made by turning an interpreter into a compiler would be woefully inefficient because it wouldn't be at all optimized.
As to your original question about whether you could take the JVM's JIT and use it to produce raw machine code for a Java program, I'm not sure since I haven't looked at the source code, but I strongly doubt it. The machine code almost certainly contains hooks that would call back into the JVM for specific tasks (for example, garbage collection, class loading, etc.), which would make the generated code not work in a standalone environment. However, it is a really cool idea to try to do this, and I hope that this answer shines some light on the theory behind it!
Please note that this question is similar to "Can I get rid of Windows and let my Windows program run on the bare metal without an operating system"?
Java programs expect a large set of classes to be readily available, which is what the JRE provides, and that any compiler or emulator will have to provide too.
What you can do however is to look at a launcher which will allow you to bring your own JRE with your application - this will only work at the platform of the JRE, but you are already willing to be platform specific. Several exist - I encourage you to look at the many questions already on Stack Overflow about how to do that.
I need to compile and run a c++ program from java. I am using
Process a = Runtime.getRuntime().exec ("g++ -g function.cpp -o function");
Process b = Runtime.getRuntime().exec ("./function");
the problem is that the output I get from the c++ program is not correct but If I compile and run it myself in the command line it works just fine. The problem is Java and i dont know why.
Thanks a lot
Al,
There is one definite and one probable problem that I see here. The definite problem is that Runtime.exec() does not wait for the process to complete. So you will need to add
a.waitFor();
before calling b.
The possible issue is that depending on how you are invoking this application, the current working directory may not be where you think it is. So function.cpp may not exist.
Are you waiting for process A to finish before running process B?
"The output... is not correct" doesn't help anyone to diagnose your issue. You should definitely give the output you expected, and the output you saw from Java. Assuming that your program is small, you should post the source code of that too (since this is about the compilation process after all).
By the way, what happens when you navigate to the working direction of the Java program, find the function executable it generating and invoke that yourself from the command line? Is the output correct now? The answer to this will let you know whether the problem is in the compilation step or the execution step.
If it's execution, I would hazard a guess at things like the environment (envvars, PATH, etc.) but without more information it's hard to tell.
Also, as with all question that involve Processes, take a look at these common pitfalls. It looks like you're making at least one of them (the common one of not consuming output) which might lead to your program working on trivial C++ code but deadlocking on a larger codebase.
You're also not checking the output (either the return value or the stdout/stderr streams) of the compilation step at all, so you have no idea whether the compilation was successful - and if not, what (useful) error messages you got from the compiler.
Is there a way to reconstruct the command line arguments passed to Java within a Java program, including the JVM options and classpath option?
I have a Java program that needs to restart the JVM and manipulate its bootclasspath (i.e. trying to override some system classes). I use the libc system method to invoke the new JVM.
I'm open for better approaches, but Java agents isn't an option.
Why not use a file that has these properties just like the Eclipse ini file and NetBeans conf files. That way you just read these properties and spawn the new Java process with these properties.
Back to your question, this previous answer should do
I agree that futzing with the bootclasspath is generally a poor idea. But...
Grab the code for "java.c" - the C program that compiles down to java.exe. You'll find that it just uses the JNI Invocation API to construct a JVM and call the main method. You could modify and re-compile this to look for particular exit codes, etc. and loop around and re-launch the JVM if required.
Alternatively, Eclipse does this (or at least used to), but having one Java program construct the command line (from a props file, etc.) and launch a sub-process. Again, it hooked the sub-process exit code and used that to decide whether or not to re-launch a new sub-process.
Err... modifying a whole core java class at runtime is a very very bad idea.
Whats wrong with subclassing here? Are you trying to modify an external library, add functionality, or be lazy?