Add or modify keywords in java language - java

I know my question does not seem valid, but it is genuine. When writing java I must use the word import so as to import classes from classpath. It is required to user new to initiate certain objects and other keywords in java. My question is whether we have even the slightest ability to improve and this great language by way of defining new keywords and what they do or modifying the exisiting keyword to do the same thing. For example instead of writing:
import java.io.File;
What possibility is there to modify the import word to bosnian for example:
uvoziti java.io.File;
and it all works the same way. Please do not close before I get ideas.

One approach that uses a rather sophisticated toolchain and could be considered as an "overkill", but is not as much effort as writing an own compiler or so:
Download ANTLR4 from http://www.antlr.org/download.html
Download the Java Grammar at https://github.com/antlr/grammars-v4/blob/master/java/Java.g4
Modify the Java Grammar according to your needs...
Run
java -classpath "antlr-4.4-complete.jar" org.antlr.v4.Tool Java.g4
This will generate some files, one of them being JavaLexer.java.
Create a Java Project that contains the ANTLR JAR and the JavaLexer.java
Create a class like the following, which does the translation:
import java.io.IOException;
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;
public class Main {
public static void main(String[] args) throws IOException {
CharStream s = new ANTLRFileStream("Input.javaX");
JavaLexer lexer = new JavaLexer(s);
TokenStream t = new CommonTokenStream(lexer);
int i = 1;
while (true) {
if (t.LA(i) == -1) {
break;
}
if (t.LA(i) == JavaLexer.IMPORT) {
System.out.print("import ");
} else {
System.out.print(t.LT(i).getText() + " ");
}
i++;
}
}
}
(of course, this is only an example that only translates the IMPORT token, which was defined in the grammar file to be "uvoziti". For a more general and flexible translation, one would define the translation in an external file, and probably read this file to create a map Map<Integer, String> that maps JavaLexer.IMPORT to "import" etc...)
Create the input file from the example: Input.javaX:
uvoziti java.io.File;
public class Input
{
public static void main(String args[])
{
File file = null;
System.out.println("done");
}
}
When you then run the Main, it will read this input file, eventually find the IMPORT token, and instead of the original text (uvoziti) it will print import.
The result will be the contents of a Java file, with an awful formatting...
import java . io . File ; public class Input { public static void main ( String args [ ] ) { File file = null ; System . out . println ( "done" ) ; } }
but fortuntately, the compiler does not care about the formatting: You may write this output directly to a .java file, and the compiler will swallow it.
As it is described here, it is only a proof of concept. For a flexible and generic translation of many (all) keywords, one would have to build some infrastructure around all that. The input files should be read automatically (File.listFiles(), recursively for packages). Each of them would have to be translated (using the Map<Integer, String> that I mentioned earlier). Then the output files would have to be written and compiled, either with the runtime JavaCompiler, or by manually invoking the javac with Runtime#exec.
But in general, I think that this should be doable within a few hours in the best case, and within one week when considering that everything takes longer than you think.
Writing an own Java compiler, on the other hand, might take a bit longer, even when you consider that everything takes longer than you think...

Java doesn't provide any way to redefine keywords.
If you add or remove keywords to the Java language, then it isn't Java anymore.
You could write your own language that compiles to Java. This could be as simple as writing a program that does a string replace of uvoziti for import and then runs it through the javac compiler.

As an option, use something like preprocessor or write your own one, to process java code via replacement of bosnian words to english ones before passing this code to the javac compiler.
I think this approach should work for your case.

Java by itself doesn't help you in this.
You might want to pass your code through a pre-processor, but things start to look a bit crazy: Can I have macros in Java source files.
I've never done something like this, so I'm not sure it will work as intended.
Also, consider that after this change your code is only readable by people understanding bosnian.

You can't really solve this to work generically; java strictly defines the keywords in its language specification and there is no mechanism in the java language to add keywords (e.g. macros).
A partial solution would be to create a preprocessor that translates your new keywords into plain java. Needless to say that this is a pain to integrate into common tool chains and you won't get useful compiler error messages any more for constructs created by the preprocessor.
One step further would be to write your own compiler; again this integrates poorly with existing toolchains. You still don't get proper support from your IDE.
As fascinating as the idea is; the obstacles make it highly impractical for generic use.
The situation is different in languages that come with a compile time macro language (most assembler langauges have this). C's define is another example. They still all have the problem that they are preprocessor based, so added constructs are more complicated (only basic syntax checking etc.)

JVM and JDK understands Java key words. If you want to change into you language, then you have to change JDK and JVM also.

Just use a preprocessor. If java doesn't have one , then write one.

Related

Java: Finding which lines an import (package or relevant Jar) is used

I want to know which line(s) are using a given import in a Java file.
Imagine having this Java file. How can we tell which lines are using a method or constant provided by each import (their package). Only methods or constants that are listed on Oracle Java API docs or jars.
# SomeFileYouReceived.java
package xxxxx;
import java.util.Stack;
public class SomeFileYouReceived ...
{
...
private Stack fMethodStack= new Stack();
...
public boolean processesEnclosingMethod() {
if (fMethodStack.isEmpty())
return false;
return getEnclosingMethod() == fMethodStack.peek();
}
}
For example, in case of import java.util.Stack, these lines used Java Util package:
1- private Stack fMethodStack= new Stack();
2- if (fMethodStack.isEmpty())
3- return getEnclosingMethod() == fMethodStack.peek();
extra info 0: There might be many imports in a file so an efficient process is desired. Ignore the local packages.
extra info 1: If needed, the whole source code can be checked out (not just the file).
extra info 2: The commits arrive to a node running Python on Docker, so obviously IDE tool are not useful but I can run shell, Java commands or a parallel Java node if it would help.
What you want is impossible, and you do not appear to understand how java works.
I better provide some details to back up that statement. I'll provide a few scenarios where what you want to do is not properly defined.
Imagine that exact, entirely identical file, except instead of an import statement plus new Stack(), the file contains no import statements whatsoever, and instead contains new java.util.Stack(). This file is valid java and is in fact 100% identical - same bytecode.
Or, even more complicated:
package a;
import java.util.Stack;
public class Somewhere {
public static Stack makeStack() { return new Stack(); }
}
and then the target file you want to analyse looks like:
package b;
import a.Somewhere;
public class Example {
public void method() {
makeStack().isEmpty();
}
}
Does this 'use' Stack? There is no import, whatsoever.
Or how about this one:
import java.util.ArrayList;
public class Example {
void test() {
var list = new ArrayList<String>();
System.out.println(list.toString());
}
}
Does the call to toString() count? The signature is defined by java.lang.Object, but the implementation is provided by java.util.ArrayList. If you think that means it should 'count', note that it is impossible to know, that's the point of OO. You don't care where the implementation is from, you just care that it exists.
A few notes if you really do want to continue down this crazy road:
You'd need a java parser that fully links all sources to get anywhere. This is incredibly complicated and requires quite some java expertise, even then, we're talking many weeks of development effort. You'd start with javac itself (which is GPL open source) or ecj (which MIT open source), and read up on how to get them to process those java files into Abstract Syntax Trees, attribute them, and then you could possibly do this job.
It's a lot easier to scan class files instead and simply look through the constant table for references to the types you are interested in. This makes import statements entirely irrelevant (In java, an import statement is just an aliasing. import com.foo.Bar; means: "Whenever Bar shows up anywhere in this source file in a place where a type is needed, assume that means com.foo.Bar. An import statement in java does not run any code. It is nothing like python's import in any way. This solution will find any invokes to anything defined in a type you're interested in, and will not find anything defined at a higher level (even if the implementation is provided by a type you're interested in), which follows how java is designed (which is: You can't care about who provides the implementation, it's literally not knowable in the vast majority of code cases unless you run it, and then you get into the halting problem if you want to do that kind of analysis). You can use BCEL, ASM, ByteBuddy, and a few other libraries to read class files.
You can chain these 2 things: Fetch some java files, compile them, then analyse the resulting class files using e.g. BCEL, ASM, ByteBuddy, yadayada.
Note that in python none of this is possible at all, as python is entirely dynamically typed. It is not possible to 'link' a method's name to an implementation or even a type, except using heuristics which are (by definition) unreliable. You can know this stuff if you run the code, but the Halting Problem would again ruin your day. In java a few interpretations of your question are at least possible, if difficult. (see #1).

Is there a way to call imagej macro (.ijm) from java (i.e. have macro stored as string and execute it using a java control of imagej)?

It is reversed problem to:
How can I call/execute a java program from an ImageJ macro?
Whenever I write imagej I refer to fiji.
Of course a trivial solution is to create a .ijm from java string and call imagej using a system call with .ijm as an argument, but I search for better solution. Alternatively .ijm instructions can be translated into java calls but it is not very convenient (when .jvm is enough for the job it is very convenient way to keep it in this format).
Why is it useful? It can be used e.g. to distribute a .ijm macro in obfuscated way - make it more difficult to the user to extract the macro. String containing instructions for .ijm can be decrypted only when correct password is provided, etc. Thank you for any suggestions!
Use the ij.IJ.runMacro(String) method.
Here is an example:
import ij.IJ;
import ij.plugin.PlugIn;
public class Run_Macro implements PlugIn {
#Override
public void run(final String arg) {
final String macro =
"run(\"Clown (14K)\");\n" +
"run(\"Make Binary\");\n";
IJ.runMacro(macro);
}
}
A word of warning about obfuscation, though: Java is notoriously easy to decompile.
Correct me if I am wrong but one could call IJ.runMacroFile to refer to a given macro text file in the macro folder.
public void My_Macro() {
IJ.runMacroFile("My_Macro.txt");
}
Yet I don't know if you can run macros outside of the macro folders, for example from within a .jar

Is Compiling String as code possible?

I have an app that gets the content of an html file.
Lets say the text of the page is:
String[] arr = new String[] {"!","#","#"};
for (String str : arr) {
write(str);
}
Can I somehow compile this text and run the code within my app?
Thanks
Use Janino. It's a java runtime in-memory compiler. Way easier than BCEL and the likes.
From the homepage:
"What is Janino?
Janino is a super-small, super-fast Java™ compiler. Not only can it compile a set of source files to a set of class files like the JAVAC tool, but also can it compile a Java™ expression, block, class body or source file in memory, load the bytecode and execute it directly in the same JVM. Janino is not intended to be a development tool, but an embedded compiler for run-time compilation purposes...
You can use the javac compiler, or the Java Compiler API or the BeanShell library (or similar). You can compile it any number of ways, none terribly simple which often leads to finding another way to solve your problem.
Instead of generating source and compiling its common to generate byte code directly using ASM, Javaassist, BCEL or the like
This appears to be the same as
for(char ch: "!##".toCharArray())
write(ch);
which is likely to be the same as
write("!##");
Since the question is tagged android:
The answers posted so far only apply to the “standard” JVM, not to Android's Dalvik VM. In principle, it is possible on Android too. I don't know if there's an existing Java compiler that you can embed, but you would probably generate the final Dalvik bytecode using dexmaker. It may be possible to combine an existing Java compiler with dexmaker.
But please think twice before attempting anything like this, and be very careful. The last thing you want is a way for an attacker to execute arbitrary code on your user's hardware.
You can try javassist, it's not full Java though.
This is not usually that hard to do, but I have to ask can you give more detail on exactly what it is you are trying to accomplish. I do this type thing all the time. This is just another example of getting information from the user and using it somewhere else in your code. Since your using java maybe look at the string API http://docs.oracle.com/javase/6/docs/api/java/lang/String.html and the string tokenizer http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/package-summary.html
Now you can break the string down into single values one word or other value at a time. From there you can use functions such as isNAN() from the float or double class to determine if it a number or string or whatever it is your testing for. Now you know what you’re dealing with you can reconstructed the data in a usable form.
Note for values if you want to use them as values use Float(string value) constructor. i.e Float x = new Float(myString)

Write Java Program to grade Scala Homeworks

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

Java packages autoimports

Is there a tool/library that allows me to import the java packages automatically outside the IDE?
For instrance if I type in notepad something like:
JFrame f = new JFrame();
Then run this magic tool, and then have automatically written as:
import javax.swing.JFrame
....
JFrame f = new JFrame();
Is there something like that? This is what comes to my mind as sample usage:
import java.io.File;
public class TesteImport {
public static void main(String[] args) {
AutoImport autoImport = new AutoImport();
File clazz = new File("SampleClazz.java");
autoImport.setImportClass(clazz);
autoImport.addLib("LibA.jar");
autoImport.addLib("LibB.jar");
autoImport.importAll();
}
}
Even if there is such a tool, it won't work always automatically without user input.
If you have for example this code:
List myList;
It has to ask, if the List should be from java.awt.List or java.util.List.
In Eclipse, you have Crtl-Shift-O (or Command-Shift-O on a mac). Perhaps you could dig into the Eclipse source code (open source) and find the Java code that drives this feature and re-use it. Good luck!
What you are asking for is a tool that will modify your source code outside of the IDE. That's really not a good idea--codegen always ends up sucking, no matter how cool and limited it seems at first.
The only decent case for code generation is where the programmer NEVER sees the intermediate version--this happens with C preprocessor--it makes an intermediate pre-processed version that you never see.
That said, what you might want is something like Groovy. IIRC, groovy allows something like "import *" for import everything.
The thing is, Java is more of a professional tool--you really don't WANT it doing tricky things. Many Java programmers don't even like "import java.util.*" and insist on expanding the exact imports so that you know exactly where each class is coming from.
With lighter languages like groovy, ruby, etc this isn't really as much of a problem--being terse is more important.
PS. If you have to use Java, honestly the answer is no, there is no good solution outside the development environment GUI. Embrace your GUI.

Categories