So I have a jar file that contains scala as the source code and I have lost the original code. Is there a way to convert the class files in the jar to scala functions and classes instead of the java classes the compiler makes?
I have tried using a decompiler on it and it only gives me the java code that makes zero sense.
Thank you in advance!
You'd need a Scala-specific decompiler. There is no reason one couldn't be written, but it would be a large effort and so far as I know nobody has actually done it. Of course, it wouldn't produce exactly the original code, just as decompilers for other languages don't.
Scala compiles to JVM bytecode, which is the same compilation target as Java. Unless the decompiler targets Scala explicitly, decompiling to Java makes sense.
To complement the information in Alexey Romanov's answer, which is still current and valid for Scala 2, I'd like to add that since Scala 3 (a.k.a. Dotty, its development name), Scala first compiles to an intermediate representation, TASTy (which adds Typed Abstract Syntax tree information to the compiled classfiles -- hence the name).
You can see an presentation about TASTy and its role in the compiler pipeline in this interesting talk at Scala Days 2019.
As mentioned in the talk, Dotty natively offers the possibility of decompiling the compilation output (TASTy + classfiles).
As a simple experiment, let's consider this very simple program in a file Main.scala:
object Main {
def main(args: Array[String]): Unit = {
println("hello, world")
}
}
Running dotc Main.scala on it produces the expected output (a .class file for the Main class, one for the Main object and a .tasty file), which can be fed back into the (de)compiler with the -decompile option, as follows:
dotc -decompile Main
The output of this command is the following:
/** Decompiled from ./Main.tasty */
#scala.annotation.internal.SourceFile("Main.scala") object Main {
def main(args: scala.Array[scala.Predef.String]): scala.Unit = scala.Predef.println("hello, world")
}
You can follow the instructions here to get started with Dotty and perform the same experiment as I did, which was run with Dotty 0.27.0-RC1.
Related
I am having a rather interesting scenario here. Let's say I have a piece of C code stored in a Java String. I need to run this code inside my Java program it self.
Case 1
class Main{
public static void main(String[] args) {
String cCode = "printf(\"Hello World\n\");"
// I need to run the cCode here.
// We are allowed to call a method with params.
}
}
What I think I should do is.
Create a native field in the Main
write the sCode to a file
Exceulte shell commands from Java to compile the c code.
invoke the native method from java
Case 2
I am thinking of doing the above procedure because I know how to do this with JNI if the source code is pre-defined.
class Main{
static {
System.loadLibrary("Main"); // Load native library at runtime
}
private native void sayHello();
public static void main(String[] args) {
new Main().sayHello();
}
}
In the case of pre-written C code. What we do is.
Compile the java class with javac Main.java
Generate the header for C lib. javah -jni Main
Complete the Main.c by writing the C code
Compile the C code with gcc -share -I/path/to/jni -I/path/to/jni_md -o Main.so
Run Main. java Main
Can anyone tell me whether I am taking the correct path (in Case 1) or not? or is there is a better way to do it?
** Note: The key point here is, I am allowed to compile the java code only once. (At the beginning).**
EDIT: After checking the comments and answer from #Dúthomhas I think I should explain one more thing. The reason why I am doing this for a machine learning project. It has been decided that the numeric computation part has a bottleneck and using C as the above-mentioned method is worth the risk of trying it. So security is off the book right now. We just need to do this as an experiment.
Non-answer answer: Don’t do that.
What you are asking to do is a pretty bad idea for several reasons, the two major ones are:
It potentially opens (serious) security holes
Cost to implement likely outweighs the benefit
Asking to embed an entirely different language means adding and linking a library and a lot of code to synchronize the library, plus code to perform static analysis and sandbox the code. In other words, you are asking to implement an entire language on top of what you already have.
It could be argued that C is the base system anyway, upon which the JVM may even be implemented (usually is), but that is not the point. The issue is not the C library, it is the C compiler/interpreter, which is a fairly complex code base as far as simple interpreted programming languages go.
Suggestion: Use Java
The ToolProvider class is specifically designed to provide you with dynamic compilation of Java code. Take a look through it.
Make sure to use the SecurityManager class to properly sandbox the code. (And, if possible, run it in a separate, restricted JVM.)
Suggestion: Use JavaScript/ECMAScript
The ScriptEngine classes are designed exactly for this. Again, Google around for examples. And, again, don’t forget security.
Suggestion: Use an existing library
FScript
Scheme
Tcl
Python
But I really want/must use C
Alas. It is possible to use C, but only with great difficulty. Google around “embedded c interpreter” for small C interpreters that you may be able to integrate into your source. (Good luck, though!)
Let me clarify your two Cases.
Case 1 refers to running a C program out of process. This is not what most people consider "invoke the native method from java". You cannot create a native field in Main. Actually, Java does not have native fields, only native methods. But in Case 1, you don't use native methods, either. You can compile and run any program, written in C or any other language (provided a compiler is available in the runtime environment). To do so, you use shell commands (Runtime.exec()) both to compile the program and to run it. Parameters for the C program can be passed 'on the command line' as specified in Runtime.exec(). It can communicate with your Java process with any IPC of your choice. Typically, we simply use a pipe to read the stdout of the child process.
Case 2 runs the native code in-process, using JNI (Java Native Interface). The flow that you describe here is correct, but you can modify it to use a shared library that is built at runtime. First of all, remove the native method and also loadLibrary() to a separate class. Make sure that the classloader loads this class only after your Main class runs the gcc -o libMain.so command (using the same Runtime.exec() as in Case 1). This way, the static constructor will load the freshly built library.
In both Cases you don't need to recompile your Java. You don't need to run javah to build libMain.so - this is a convenience step only, to guarantee that the C headers are in sync with the Java class. But in your situation, the Java class does not change - therefore the native method signature does not change, too.
Note that Case 1 is easier, especially if you must run different compiled C 'strings', but Case 2 may deliver better performance, if you must call the native method many times.
I want to call Rust code from Java / Android, and I've found 3 variants to do so:
JNI
JNA
JNR FFI
JNI looks good and powerful enough, but you have to
write too much code by hand.
JNA, if not taking into consideration that it crashes on my machine, requires writing Rust struct data type description in Java by hand,
the same problem with JNR FFI.
So I wonder how difficult will be generate JNI code
for traits and struct with macros or a compiler plugin?
This compiler should match traits implementations for concrete struct,
and also struct
#[JNI]
struct Foo {
a: i32,
}
trait Boo {
fn f(&self, b: f64) -> f64;
}
#[JNI]
impl Boo for Foo {
fn f(&self, b: f64) -> f64 {
0f64
}
}
and create Java classes for struct and Java classes with native functions, plus generate pub no_mangle functions that wrap traits functions.
In order to provide #[jni] annotations that work like that you'd need to use a compiler plugin. It would be an awesome tool, but it doesn't exist yet, as far as I know.
There are bits and pieces of tooling lying around that might be helpful, if you want to create a project that does this.
Plugins are currently unstable, and don't work on non-nightly rust; you would probably want to use syntex, which provides a stable interface to compiler plugins. You could also write a raw plugin (see here for the API for those), but most people won't be able to use it.
There's rusty-cheddar, which generates c header files; you could take a look at that to see how it works. The author of that also seems to be working on a more general bindings-generation framework, but I don't know if it's active. You might be able to hook the output of cheddar up to something like JNAerator, but it probably won't create the prettiest interfaces on the java side.
There's also rust-bindgen and corrode, which work in the other direction; they translate c headers and arbitrary c code to rust respectively. I don't know if that's actually helpful.
JNI-sys provides low-level JNI bindings; rust-on-mobile is a small project that uses it. Also see First steps with Rust and Java, a blog post that shows some rudiments of getting things hooked up.
Finally, there's cbox, which lets you work around awkwardness with ownership and FFI.
Finally I created such project (link to github repository) to automate
binding creation.
You can use jnaerator to auto-generate your structure mappings for JNA.
Alternatively, if you want to use JNI (and compile some more native code) you should go with SWIG.
I know it's possible to do nice stuff with Reflection, such as invoking methods, or altering the values of fields. Is it possible to do heavier code modification, though, at runtime and programmatically?
For instance, if I have a method:
public void foo(){
this.bar = 100;
}
Can I write a program that modifies the innards of this method, notices that it assigns a constant to a field, and turns it into the following:
public int baz = 100;
public void foo(){
this.bar = baz;
}
Perhaps Java isn't really the language to do this kind of thing in - if not, I'm open to suggestions for languages that would allow me to basically reparse or inspect code in this way, and be able to alter it so precisely. I might be pipe dreaming here though, so please tell me if this is the case also.
Just adding a suggestion from a friend - Apache Commons' BCEL looks excellent:
http://commons.apache.org/bcel/manual.html
The Byte Code Engineering Library (Apache Commons BCEL™) is intended to
give users a convenient way to analyze, create, and manipulate (binary)
Java class files (those ending with .class). Classes are represented by
objects which contain all the symbolic information of the given class:
methods, fields and byte code instructions, in particular.
Such objects can be read from an existing file, be transformed by a
program (e.g. a class loader at run-time) and written to a file again.
An even more interesting application is the creation of classes from
scratch at run-time. The Byte Code Engineering Library (BCEL) may be
also useful if you want to learn about the Java Virtual Machine (JVM)
and the format of Java .class files.
You are looking for software that allows you to do bytecode manipulation, there are several frameworks to achieve this, but the two most known currently are:
ASM
javassist
When performing bytecode modifications at runtime in Java classes keep in mind the following:
If you change a class's bytecode after a class has been loaded by a classloader, you'll have to find a way to reload it's class definition (either through classloading tricks, or using hotswap functionalities)
If you change the classes interface (example add new methods or fields) you will be able only to reach them through reflection.
It's probably fair to say that Java wasn't designed with this purpose in mind, but you can do it potentially. How and when depends a little on the ultimate aim of the exercise. A couple of options:
At the source code level, you can use the Java Compiler API to
compile arbitrary code into a class file (which you can then load).
At the bytecode level, you can write an agent that installs a
ClassFileTransformer to arbitrarily alter a class "on the fly"
as it is loaded. In practice, if you do this, you will also probably
make use of a library such as BCEL (Bytecode Engineering
Library) to make manipulating the class easier.
You want to investigate program transformation systems (PTS), which provide general facilities for parsing and transforming languages at the source level. PTS provide rewrite rules that say in effect, "if you see this pattern, replace it by that pattern" using the surface syntax of the target language. This is done using full parsers so the rewrite rule really operates on language syntax and not text; such rewrite rules obviously won't attempt to modify code-like text in comments, unlike tools based on regexps.
Our DMS Software Reengineering Toolkit is one of these. It provides not only the usual parsing, AST building and prettyprinting (reproducing compilable source code complete with comments), but also supports symbol tables and control and data flow analysis. These are needed for almost any interesting transformations. DMS also has front ends for a variety of dialects of Java as well as many other languages.
Bytecode transformers exist because they are much easier to build; it is pretty easy to "parse" bytecode. Of course, you can't make permanent source changes with a bytecode transformer, so it is lot less useful.
You mean like this?
String script1 = "println(\"OK!\");";
eval( script1 );
script1 += "println(\"... well, maybe NOT OK after all\");";
eval( script2 );
Output:
OK!
OK!
... well, maybe NOT OK after all
... use a scripting extension to Java. Groovy and other things like that would probably allow you to do what you want. I've written a scripting extension which integrates with Java through reflection almost seamlessly myself; contact me if you're interested in the details.
I am a TA for a programming class. There is one assignment in which the students have to write Scala. I am not proficient enough in Scala to read it quickly to verify that the program works or capable of quickly writing a script in Scala to run test inputs.
However, I am very capable in Java. I need some advice on a simple way to grade Scala assignments using my knowledge of Java. Is there a way to load in a Scala file into Java so I could have some simple Java methods to run test inputs for their programs? I am aware of the fact that they both compile to Java byte code, so I figure this should be possible.
Scala generates class files. Scala class files can be run with java, only requiring the scala-library.jar to be on the class path. The entry point on Scala programs appears to Java as a static main method on a class, just like in Java. The difference is that, in a Scala program, that main method is a method declared on an object. For example:
Java:
public class Test {
public static void main(String[] args) {
}
}
Scala:
object Test {
def main(args: Array[String]) {
// or:
// def main(args: Array[String]): Unit = {
}
}
The idea of testing by giving unit tests is interesting, but it will probably force non-idiomatic Scala code. And, in some rare cases, might even prevent the solution to be written entirely in Scala.
So I think it is better to just specify command line arguments, input (maybe stdin), and output (stdout). You can easily run it with either scala Test parms, or java -cp /path/to/scala-library.jar Test parms.
Testing input on individual functions might be a lot harder, though, as they may require Scala classes as input, and some of them can be a bit tough to initialize from Java. If you go that route, you'll probably have to ask many more questions to address specific needs.
One alternative, perhaps, is using Scala expressions from the command line. For example, say you have this code:
object Sum {
def apply(xs: Seq[Int]) = xs reduceLeft (_ + _)
}
It could be tested as easily as this:
dcs#ayanami:~/tmp$ scalac Sum.scala
dcs#ayanami:~/tmp$ scala -cp . -e 'println(Sum.apply(Seq(1, 2, 3)))'
6
To do the same from Java, you'd write code like this:
import scala.collection.Seq$;
public class JavaTest {
static public void main(String[] args) {
System.out.println(Sum.apply(Seq$.MODULE$.apply(scala.Predef.wrapIntArray(new int[] {1, 2, 3}))));
}
}
When you put the .class files generated by the student's code into your classpath, you can simply call the methods which your students developed. With a good Java IDE, you will even have code completion.
Rephrase the question: Assume you have a Java library that you need to test. But you only have the class files, not the source code. How do you do it? - Now, it's exactly the same case with Scala. In some cases, you will need to access strange static variables (such as $MODULE), but that should not be a hindrance. tobym has pointed you in the right direction with his answer.
But seriously, what can be the didactic value for the students? You will only be able to tell them whether or not their programs do the right thing, but you cannot point out to them exactly what mistake they made and how to correct it. They will already know by themselves whether or not their programs are correct. When they made errors, just telling them that they made something wrong won't help them at all. You need to show them exactly where the mistake was made in the code, and how to fix it. This is the only way you can help them learn.
If it is only one assignment and not more, maybe you can find a better way. Maybe you can invite another student who is proficient in Scala to help you out with this. Or maybe you can show some of the erroneous programs to the whole class and initiate a discussion amongst the students, in which they will find out themselves what went wrong and how to correct it. Talking about code in this way can help them a lot, and, if done right, can be a valuable lesson. Because this reflects what they will do later in business life. There won't be a prof telling them how to correct their errors. Instead, they will have to figure it out together with their coworkers. So maybe you can turn this lack of knowledge on your part into an opportunity for your students.
You can compile Scala into a .class file (e.g. "scalac ./foo.scala") and run methods from your Java grading program.
This might be useful reference: How do you call Scala objects from Java?
Well, you could write unit tests (with JUnit, for instance) before the assignment and have the students write the programs to conform to the tests.
Or you could decompile scala to java (with JD-gui, for instance).
But to be fair, if the students are only going to use scala for this one specific assignment, chances are that they are mostly going to translate directly from java to scala, intead of writing idiomatic scala. In that case I'm sure you will be able to understand scala code very easily as it will look almost exactly like java...
You can run
scalac SomeProgram.scala
scala SomeProgram input1
a lot of time during the time it would take to write some java that triggers scala compile and running of the bytecode generated
I have a Python interface of a graph library written in C - igraph (the name of library). My need is to invoke the python modules pertaining to this graph library from Java code. It goes like this, the core of library is in c. This core has been imported into Python and interfaces to the functions embedded in core are available in Python. My project's rest of the code is in Java and hence I would like to call the graph functions by Java as well.
Jython - which lets you invoke python modules with in Java was an option.I went on trying Jython to discover that it will not work in my case as the core code is in C and Jython wont support anything that is imported as a c dll in python code.I also thought of opting for the approach of calling graph routines directly in c. That is without passing through Python code. I am assuming there must be something which lets you call c code from Java, how ever I am not good in C hence I did not go for it.
My last resort seems to execute Python interpreter from command line using Java. But that is a dirty and shameless. Also to deal with the results produced by Python code I will have to write the results in a file and read it back in java. Again dirty way.
Is there something that any one can suggest me? Thanks to every one giving time.
Thanks Igal for answering. I had a look at it. At first glance it appears as if it is simply calling the python script.
Jep jep = new Jep(false, SCRIPT_PATH, cl);
jep.set("query", query);
jep.runScript(SCRIPT_PATH + file);
jep.close();
Isnt it very similar to what we would do if called the python interpreter from command line through a Java code.
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("python test.py");
Concern is how do I use the results generated by Python script. The naive way is to write them to file and read it back in Java. I am searching for a smarter approach.Thanks for suggestion anyway.
Never tried it. But I recently stumbled on a project named Jepp that may be of interest to you.
Jepp embeds CPython in Java. It is safe to use in a heavily threaded environment, it is quite fast and its stability is a main feature and goal.
If you want to call C functions from Java, JNA (Java Native Access) is probably the way to go. JNA allows you to call functions in native libraries without having to write the C glue code (as you would have to when using JNI), and automatically maps between primitive data types in Java and C. A simple example might look like this:
import com.sun.jna.Native;
import com.sun.jna.Library;
public class PrintfWrapper {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)Native.loadLibrary("c", CLibrary.class);
void printf(String formatString, Object... args);
}
public static void main(String[] args) {
CLibrary.INSTANCE.printf("Hello, world\n");
}
}
However, things will get complicated with igraph because igraph uses many data structures that cannot be mapped directly into their Java counterparts. There is a project called JNAerator which should be able to generate the JNA source from igraph's header files, but I have never tried it and chances are that the results will still need some manual tweaking.
Also note that a Java interface for igraph is being developed slowly but steadily and it might become useful in a few months or so.
You can use jep.getValue() to retrieve a value from script's global dictionary.
There are caveats to that concerning scope levels in Python, so most people find it clearer to pass a Java class to python and set the return value in that instance in Python. After the script completes, the Java code will then have the result.
For example:
==> Java
class ReturnValueClass {
public int scriptResult;
};
ReturnValueClass value = new ReturnValueClass();
jep.set("retval", value);
==> Python
# do something
pass
# write the return value
retval.scriptResult = some_python_value
==> Java
System.out.println(value.scriptResult);
Hope that helps,
Mike (I wrote Jep)