how to change .class file to a text file - java

I'm trying to make a java program which executes java files and gives output in the text field. I've used Runtime class to compile the .java file .So how do I get the output from that newly made class file.
Runtime.getRuntime().exec("javac Y://CodeSave.java");
Runtime.getRuntime().exec("java Y://CodeSave.class>output.txt");

In the general case: exec returns a Process instance which has accessors (getOutputStream, etc.) for the I/O streams. You read from / write to those streams.
But: In your code you've used >output.txt. That's a shell feature. If you want to do it that way, you need to spawn a shell, not the java tool directly, and have the shell execute that command line. (A search for spawning/execing a shell should find you lots of examples.)

Using Runtime.exec is definitely not the right way to do it, for various reasons. Examples are that both java and javac rely on environment variables which you can't pass that way.
First of all, I'd ask myself if I really needed to do this. Compiling and executing dynamically created code is a huge security risk.
But if you're sure you need to do it, here's what I'd do.
Move your sources to a dedicated temporary folder
Use the ToolProvider api to compile your sources
Use a dynamic throwaway ClassLoader (ByteBuddy may help you there) with a SecurityManager to load and execute your code from within your application

Related

Debug compiled Java .class files in VS Code

I'm taking a CS Data Structures course, and I want to try and work with VS Code instead of the current editor that I'm using (BlueJ). However, my work is evaluated based on whether it can satisfy a certain set of tests presented by a compiled tester file (a .class file that I can use to run/check my work), something that VS Code doesn't seem to particularly like.
This tester is what contains the program's main() method, so I either need to use BlueJ (which already supports running compiled classes) or run the file from the command line (something that I know how to do, but have found somewhat tedious) in order to run the method. Is there a way that I could configure a VS Code Java debugger to execute the main() method located within my compiled tester file?
A note: These tester files do not come with editable .java counterparts; if we were able to see what the tester checks for, that would ruin the point of the tester!
Not exactly what you want, But:
For tedious commands, you could set up an alias in your $HOME/.bash_aliases file.
Bash Aliases .
i.e one i aliased earlier :
alias ds="java -cp $HOME/javaWorkScripts/jspDatabaseApp/bin/ FormatTabContents $HOME/VSCODE\ Research/SURFACE-TIDE-JSP-DATABASE-APP-22-DEC-2018.txt "
From now on, you could just type ds in terminal to run the command.
You can decompile and debug the class in IntelliJ easily. Then set break points on main method and check it.
You can decompile the class in VS code easily but I doubt you will be able to debug the .class file in VS Code.

How to use clojure files dynamically?

I want use java code to run some clojure files dynamically which are in some zip files.
If the clj.p1.core.clj is on the class path, it can runs correctly.
require.invoke(Clojure.read("clj.p1.core"));
How to make it dynamically?That is, put clj.p1.core.clj in the a1.zip (maybe some files), the java program could select the zip and then run it?
Probably, you should unzip those files first and then specify a *.clj file when invoking Compile class; take a look at its sources.
What would be much better in your case is to compile a Java class from Clojure sources first and then load that class in Java as well. Just add a specific step into your build process that cares of it. In that case, your Java code will look much simpler and wont' waste time on loading Clojure code dynamically.
Creating a Java file would be easy; just wrap Clojure sources with additional namespace with gen-class declaration. Move its output into your Java project or specify classpath properly. See gen-class page for more examples.

How to run a Java (.jar) in R?

Is there any way to run a Java jar file in R? I want one of the outputs of a .jar be used in R.
You can use system to run an operating system command from R.
To run a java jar on a well-configured system, this should work:
system("java -jar /path/to/my.jar")
You can add other parameters, for example maybe the Java code takes input from a file which you write with R and pass the filename. Then output from the Java code could be written to files and then read from R. Without knowing what the Java code does we can't be more specific.
It is possible to directly interface with Java code but that requires full knowledge of the internals of the jar so you know what functions to call with what parameters. This is usually referred to as the "API" for that Java.
Otherwise, write a file, call system, read a file, is sometimes the simplest way to run code in other languages.
Java's .jar can only be run by java; so what you need is a way to run an external command from R. The command will be java, with arguments -jar and your.jar.
As far as I can tell, you need to use system function, something along the lines of
javaOutput <- system("/usr/local/bin/java -jar your.jar", intern = TRUE)
(note I have not tested that, so please do test)

How do I create a Unix load card for a java program

In Unix (or Linux), if I want to run a shell script, I can start the file with #!/bin/sh. With awk, I start the executable file with #!/usr/bin/awk -f and it treats the rest of the file as the program.
How do I do that with a Java program? I tried copying the simple.class to simple, putting #!/export/appl/Mail/java/bin/java at the top and making the file executable, but I get:
69> ./simple
Error: Could not find or load main class ..simple
I know this can be done with an executable shell script, or a C program that execs the java interpreter. Every other interpreter on Unix can be called with a #! load card, surely there's a way to do it with Java.
The most usual way is to have a wrapper for the Java. A shell script that executes the "java -jar yourJar.jar" or equivalent. And then you bundle the shell script and the windows equivalent bat file with your product.
Another option is to have a native launcher. For example you can see the Eclipse project which has gone that way. You download Eclipse and you have a native executable to run. The native executable will launch your Java program.
One more option is to compile Java into native code. For example you can use this commercial tool called Excelsior JET ( http://www.excelsior-usa.com/jet.html ).
The Java class file format doesn't allow text before the header, that's why the Java runtime no longer accepts the .class file after your modification.
On Linux you can use binfmt_misc to support additional executable formats, including .class files. It's basically a way to tell the Linux kernel how to detect executable formats and how to execute them.
This Archilinux Wiki article explains in more detail how to get this effect.
You cannot do it with a Java program. Firstly, the Java program needs to be compiled before execution. Secondly, even if compilation wasn't required, the hash sign is not a comment in Java, so that would be a syntax error.
I've never heard the term "load card". What you have is an "interpreter directive" designated by a shebang. This merely designates which interpreter the shell should invoke on a given script.
As for why C programs can be run directly in the shell, executables recognized by the operating system are passed to the loader. A Java class isn't an executable, at least to the OS anyway. So the shell must know which interpreter to pass control to.
But as you've noticed, the shebang doesn't work. The reason is that the class file is in a specific binary format that the JVM expects. Editing this file will break convention and lead to an error. Therefore, there is no way to do what you've asked.
However, you can create a "shortcut" to the program you want to run by creating an alias or perhaps writing a one-line Shell script to wrap the java command you need. This is the common practice as I understand it.
The other answers explain why you can't do what you are trying to do. However, if your shell is zsh, you can create a suffix alias. For example, to execute .jar files using java:
alias -s .jar="/usr/bin/java -jar"
Then, to execute blarg.jar, you just type ./blarg.jar. Of course, you must chmod +x your .jar file first.
Apart from the wrapper script and binfmt_misc solutions suggested by others, I'd like to suggest a potential solution which doesn't directly answer your question but maybe it solves your actual problem.
Since Scala does have an interpreter that can run code without you having to compile it first, and this code can reference any Java code, if your goal can be summed up as "using Java as a shell scripting language", you could use a .scala file as your starter script (which can include the shebang to be run with scala) from which you can call all your Java classes. This isn't any simpler tha having a bash-based starter script, but it's a good starting point to gradually move to scripting in Scala instead of Java in which case you can get rid of the need to compile to .class file in the first place.
The reason this doesn't work is that Java isn't really an interpreted language, it's partially compiled, partially interpreted.
The .java source code that you'd put the hashbang directive in needs to be compiled to a .class file before the java interpreter can run it. Comments are stripped out by the compiler, so there's no way to push a comment from the .java into the .class file. The .class file is "compiled" output in a specific format, so adding a hashbang directive to the top of it would break the format.
Java isn't really meant to be a scripting language - but some JVM languages are. For example Groovy supports hashbang and so does Clojure.

Compile and execute java source file in memory

Say I have a String containing the content of a .java file. Are any APIs out there that would allow me to compile this source file into a virtual .class file (i.e. generate and store the content in memory, NOT creating an actual physical .class file on disk)? And this "virtual" .class would then be loaded and executed in the JVM?
Edit 1: The only reason I want to do this is because sometimes, my application might not have the write permission.
Use the JavaCompiler for this. I think the trick will be to define a custom JavaFileManager.
Java does have a compilation API to compile files dynamically, but I'm not aware of an option that would not persist the class files to disk. You can always use a ClassLoader and load those classes dynamically and then use them. You might be able to load the classes in memory by overriding the getFileForOutput method.
Optionally, this file manager might consider the sibling as a hint for
where to place the output. The exact semantics of this hint is
unspecified. The JDK compiler, javac, for example, will place class
files in the same directories as originating source files unless a
class file output directory is provided. To facilitate this behavior,
javac might provide the originating source file as sibling when
calling this method.
Another option is to use an Interpreter like BeanShell that will run the java code for you. It executes script like code and can work in repl mode.

Categories