I am involved in a project that will need to run via web and have access to java's compiler tools and/or javacc api. My team is thinking of using a java applet to make it web based. I'm wondering if there are certain limitations on what an applet can and cannot do in this case. I would assume that since access to the compiler would be done on the server, not the client's machine, that this wouldn't be a problem. Does an applet allow us to separate the two as described?
An applet (and even a JavaFX applet) can work in this situation if the applet is signed. There are numerous subtle pitfalls with applets, so I would advise prototyping before committing to that technology. Follow the JavaFX deployment guide to see how to deploy a JavaFX based applet.
I had thought that to compile Java, you needed to have the full Java Development Kit installed (which would be tricky to ensure in an applet deployment situation). But it seems that the compile API is included in the javax.tools API included with the standard Java Runtime Environment. So this likely means that you could develop your solution, including client based deployment and compilation of Java code, without requiring the user install the full Java Development Kit.
You may alternately wish to consider a client/server solution where the compilation can be performed on the server. An example of such an approach (with a Java WebStart based solution) is the TopCoder Algorithm Competition Application. Here is a jnlp file (http://apps.topcoder.com/wiki/display/tc/The+Algorithm+Competition+Arena) to run this application. I suggest you register an ID at TopCoder using the application and try out writing and compiling some code using it. The TopCoder implementation uses plain Swing as it was written before JavaFX existed, but you could equally use JavaFX for your implementation if you preferred.
If you additionally need an editor (with syntax aware text styling) for the code you will be compiling, you could use something like this CodeMirror based editor embedded in JavaFX. The CodeMirror based solution wraps the editor in html based WebView control. For JavaFX 8 you will probably be able to make use of the new TextFlow control for a syntax highlighting text editor, but that API is not part of a supported public release yet.
Update
I got this work using the strategy outlined in this answer.
The image is an html page allowing access as an applet or a webstart application to the client code editor. The top area of the image is the code editing area which is based on a WebEngine with an embedded syntax highlighting CodeMirror JavaScript editor that supports Java editing. The bottom area of the image is the output of compiling the code in the editor locally on the client machine and subsequently running it. The output constists of any compilation errors, any program output to sysout, as well as any runtime exceptions printed to syserr. The tricky parts of the solution were:
Working out how to capture sysout and syserr and redirect them to a JavaFX control.
Finding the Java compiler.
The default Oracle Java Runtime Environment Provider merely provides a generic interface to a Java Compiler implementation, but it provides no java compiler implementation itself - that implementation is only included in the tools.jar included with the jdk. So when I packaged my applet, I included the tools.jar in the packaging for the applet. I had some difficulty getting the service provider interface to get me an instance of the javac compiler, so in the end, I just instantiated it using the following line:
JavaCompiler compiler = new com.sun.tools.javac.api.JavacTool();
The above is somewhat brittle as sun may change their private com.sun classes at any time - but at least it worked in this instance.
Another thing to be aware of is that if you ship a tools.jar with a javac compiler which is earlier than the runtime environment that you have available for your system, then you might get some warnings such as below:
warning: C:\Program Files\Java\jre8\lib\rt.jar(java/lang/Object.class): major version 52 is newer than 51, the highest major version supported by this compiler.
It is recommended that the compiler be upgraded.
The above warning occurred because I shipped the applet with a java 7 tools.jar and ran the applet with a java 8 runtime (note that the applet worked fine regardless of those warnings).
Update
I put the code for this solution in a github repository (project name conception). The updated solution uses the Eclipse Compiler for Java rather than the Oracle Java Compiler. Mostly because, for the Eclipse Compiler, it is a separate jar (only 1.8meg rather than the 14meg tool jar of the oracle distribution) and the licensing is a bit clearer. Because the Java compiler interface is pluggable, the Oracle compiler can still be used if tools.jar is placed on the classpath.
Yeah applets can access them and can be a good choice. But it has very limited/ dull look and feell. Go for JavaFx in this you can define your own StyleSheet so it will give you a very good look and feel and yeah definitely it will separate the two layers too.
JavaFx Oracle Documentation
Related
I found some reference that says I can add #!/usr/bin/java --source 12 at the beginning of the file and run the file directly from the terminal.
I am able to run using this on my local machine, however, when I tried the same on Github action I'm getting the error error: invalid value for --source option: 12
I'm not really an expert in shell scripting or java, can someone help me understand what this --source means is it the java version, I tried setting up the same version (jdk18) on Github action but still did not work.
java (the runtime executable) can only run class files. Until, that is, java12, where a normal JDK distribution (and not the bizarro JREs that some packagers like Azul publish ^1) has a java.exe that can run java files straight up. It's simple sugar - the compiler is still involved, of course. It's just that java will execute it for you.
You don't need --source 12; just java MySourceFile.java is fine. Edit that comment at the top of your source file, it should just be #!/usr/bin/java. The thing you do need is that java on your command line PATH is a java v12 or higher, and it is not. There isn't anything your java source file can do about this, you're going to have to impose on your users to have at least java12 installed or this simply does not and can not be made to work. It looks like you're on some linux distro or other; apt or yum or snap or whatever package manager you have will tell you how to fix this: Install java17, and uninstall the rest or use java-alternatives or whatever mechanism your package manager has to set the default executable (the one /usr/bin/java links to). Read the documentation of the package supplying java17, possibly following some links to the generalized java infrastructure package, it should tell you.
Mostly this is a red herring, this just isn't how java files are distributed. It's virtually pointless because:
Java is not a language that tends to be used for quick shell script-esque things. Such things tend to be self-fulfilling prophecies: Because nobody does this, library authors aren't thinking about it when they develop their APIs and the users of their libraries won't file enhancement requests for this either. Because common libraries aren't convenient when used for quick off-the-cuff shell scripts, java isn't used for it, thus perpetuating the cycle.
Any serious java app would definitely involve packages, dependencies, and more - and such apps cannot be run like this.
Class files are as platform agnostic as source files are. There is no sane reason to distribute java-written shell-script-esque tooling as a source file instead of a jar, except for off-the-cuff editing off them, which gets you right back to point #1 and #4.
The java core APIs work on a model of lowest common denominator: If there is a major OS that cannot or doesn't work in a certain way, then java simply does not expose this at all. For example, on all posix systems (i.e. pretty much every major OS except windows), you have your usual TERM, KILL, HUP, etc signals. Java core libs don't let you interact with them (unless you dip into hidden sun.misc.* API which doesn't reliably work in the first place). This makes java extra unsuitable for quick command line scripting where you want a different model: If at least one OS can do it, the language should have a library for it, and that library should simply fast-crash if you attempt to use it on an OS that doesn't support it. One easy way around this is a third party library that adds support for OS-specific stuff, but your model of distribution (stick #!/usr/bin/java at the top and distribute a source file) cannot include dependencies.
Java as a runtime model is mostly focused on running things eventually very quickly, at the cost of starting off slowly. This is fantastic for web servers which need to run efficiently but will be running for quite some time. It's utterly unsuitable for shell scripting, though.
CONCLUSION: You don't want to stick #!/usr/bin/java at the top even if you could make it work.
[1] A JRE is a java distribution without compilers and other development tools like jstack. These cannot run java SomeSourceFile.java, obviously; they do not have a compiler. However, JREs died - there are no JREs anymore; JDK8 is the last one that shipped with an official JRE. The JRE serves as a distribution model: The end user installs a JRE, and you ship your jars to them. This model is obsolete (you are now responsible to get something that can run your class files on the deployment machine), and therefore JREs died. However, some packagers of OpenJDK builds, such as Azul, still publish them, confusing matters. Hence, 'bizarro'. Azul and co have relatively good reasons for doing it, but, you shouldn't be using these unless you really know what you are doing.
I am currently working to find a bug in my code, and upon inspecting element on my browser (FF and GC), I found that the java source code is obfuscated by GWT in order to increase parse speed. From researching online, i found that:
If you prefer not to have GWT obfuscate its output, then you can use
the -style flag on the GWT Compiler. This flag has one of three
possible values:
OBF (for obfuscated), the default
PRETTY, which makes the output readable to a human
DETAILED, which improves on PRETTY with even
more detail (such as very verbose variable names)
I am wondering where I can find the GWT compiler.
There is no standalone compiler executable for GWT, it comes as part of GWT SDK. Download the GWT SDK and from within the SDK dir you can invoke GWT compiler.
Check this link - http://www.gwtproject.org/doc/latest/DevGuideCompilingAndDebugging.html#DevGuideCompilerOptions
I have highlighted the style option.
I wan't to create an applet that includes the Java compiler and is able to download and compile .java files from the web (or from a textfield for that matter).
From what I understand, the Java compiler is based on Java, so this should be possible.
However, one thing I wonder is wether the Java compiler is able to store the class file in memory or that it needs explicit disk access.
Also, I want to catch the errors javac produces, but this is natural.
Is there an article on this somewhere maybe? I couldn't find much on the case. What troubles could I walk into?
EDIT: I'm planning on using the applet with OpenCL, so I would have to sign the applet.
EDIT: Similar question here: Hosting the Java compiler in an applet or in Google AppEngine?
Java compiler is always with you. You should use java.lang.Compiler class. But I believe you will have issues with SecurityManager.
If I were you I'd prefer to compile code on server side. It means that I'd develop servlet that is able to get the java source and compile it. The resulted java class should be available over HTTP under path that is configured to be accessible by applet, so your applet will be able to run this class after compilation.
From the documentation on the SSCCE Text Based Compiler:
javax.tools.ToolProvider. The docs for getSystemJavaCompiler() mention that it returns "the compiler provided with this platform or null if no compiler is provided", but do not make clear why it might be null, nor the fact that the compiler will not be available to applets or webstart apps.
Hello All
I am writing some software that will allow users to create their own Java classes for a specific use in my software package. Obviously, my software will need to be able to invoke a Java compiler to compile the user-generated classes for use in my program. However, I do not want to require users to download and install the entire JDK just so they can have access to the javac Java compiler. I understand that in Jave 6 there is a new Java Compiler API but even then, users with just the JRE and not the JDK will get a null object when they try to instantiate the Java compiler tool.
So, what is the best way to enable my program to compile Java classes while requiring the end user to just have the JRE installed on their machines? If this is not possible, what is the minimal set of libraries/jar files I would need to install on the user machine?
I suppose another possibility might be to use JWS (javaws) to launch the app over the web. In this case, is it possible for my software to not require the JDK (mainly tools.jar I think)? Would I somehow have to bundle tools.jar with my software?
You can use standalone Java compiler from Eclipse. It doesn't need JDK installed, and it's single JAR file you can use in your project. This is the compiler that is used inside Eclipse itself, but it can be integrated into other programs too. You can find current latest stable version at http://download.eclipse.org/eclipse/downloads/drops/R-3.6.2-201102101200/index.php, look for Look for JDT Core Batch Compiler. Documentation is available at http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_compile.htm
You can also use Janino, which can compile also smaller units than full Java classes: blocks, expressions. It's not full compiler though, it does not support all features of Java language that your users use (generics, annotations, enums, ...)
To use the java compiler, you need to include tools.jar into your application (e.g. it has to be reachable by the classloader who wants to load the compiler - most easily by the System class loader).
Maybe http://asm.ow2.org/ this will be usefull? To generate bytecode on fly?
It sounds like a better solution would be to use some scripting language that can run within the JVM without having to be compiled.
Possible the Java Scripting API would be of use to you. I'm sure there are other options as well.
We are in process of developing a commercial desktop based application in java using Rich Client Platform framework from Netbeans/Eclipse. The IDEs (Netbeans/Eclipse) provides nice inbuilt installer for packaging the application. The only problem is our end users can see jar files on deployment and we don't have enough protection of our intellectual property as reverse engineering is possible. Code obfuscation can be used to minimize the impact but can't avoid it. We were searching for open source solutions/products which can help us mitigate our problem by directly converting our application to native code something similar to what AOT is supposed to do.
Thanks in advance for ur help.
-Bhan
this was already discussed here: How do I create an .exe for a Java program?
You may transform an Eclipse RCP applications into a real EXE (or Linux binary) containing no bytecode using the product my company makes.
In general, an AOT compiler must be aware of the inner workings of such a dynamic framework or container, specifically its class loading, otherwise the original bytecode will be required at run time for consistency checks and possible JIT compilation. Our product only "knows" about Eclipse RCP and Apache Tomcat classloaders as of now (it always knew about the standard ones of course.)