How can I skip scalac compile errors like one can with Java?
This causes the compiler to skip the erroneous file, compiling the rest, and leave the crash to run-time.
I use SBT but since it uses scalac, I think it would be a command line parameter for scalac that passes through from SBT.
Update:
My goal is to run the program, and have it fail at run-time when the error is reached.
For example, there can be a main GUI that has no errors with a button to start a server that does.
In Java the GUI will run and fail during run-time when the button to start server is clicked.
In Scala the program won't even run because the GUI file could not compile before the server file does.
Your request is against Scala's principles (don't do it, please)
This should not be possible in Scala, because it is against one of the design principles in Scala: When a program compiles, there won't be runtime errors. Of course this principle doesn't hold in all extreme cases. But people are working hard to cover all the common cases.
If the Scala compiler would provide what you are requesting, I would consider it a bug in the compiler.
How to make it work (if you still want to do it)
Of course, no one is hindering you to run programs with compile errors. It is possible up to a certain degree.
Split your program into several modules (e.g. one core and several plugins)
Compile the parts independently. When there is an error in one of the modules, Scala will not compile it)
Copy the results (where Scala produced some) together
Run the result
You could some kind of dependency injection (e.g. Guice) or some plugin infrastructure (e.g. Apache Felix) to handle the plugins better.
A personal anecdote (why you should not do it)
For one customer my team and I developed a custom programming language, complete with a runtime and an IDE (based on Eclipse xText). In an early version we had a compiler that would compile files with syntax errors. It just added additional tokens (closing brackets, keywords, missing strings or numbers) when needed until the syntax was OK again. Such a tool is very useful for syntax highlighting and completion in files that have compile errors (e.g. because the file is currently work in progress and some parts are missing). But when you run what that compiler produces, the results are hilarious at best and disastrous at worst. We quickly changed the compiler, so it will not emit runable code any more when there are any errors in the source code.
Related
I'm working on a project where we need to compile groovy classes at runtime and then instantiate objects from these classes and execute methods on it. The source for these classes exists as a string only in live environments.
These classes can contain pretty complex code, so there is a good chance of bugs hiding in there.
The problem with our approach is, that when we notice missbehavior in these classes, we can't use a comfortable method of debugging.
We can of course write and execute tests against these classes, but often times you just want to know what's going on step-by-step.
So my question is: Is there is a way to debug runtime generated groovy/Java classes?
The steps we currently take to track down bugs:
1) Write tests to reproduce the behavior
2) Read through the code. (obviously has a super bad success rate in complex classes)
3) Do instrumentation. We call a static "_break" method which we have written in a utils class (so no runtime generated stuff). In that _break method we can add a breakpoint. So this is almost as if we were debugging the runtime generated classes directly. The Problem with that approach is, that you have to recompile and add a new version of the groovy classes to the testsystem everytime you want to add/remove a _break call.
If you're wondering how we can even write tests for these classes, here is how:
For unit tests we copy the code from the strings into regular groovy classes. These are used for development and unit testing, because it gives us code completion and a fast way to at least execute the classes against simple tests.
We can debug the code on unit test level. The problem here is, that the data setup is too complex to reproduce certain combinations in unit tests.
For integration tests, we do the whole compilation, adding, executing process, just like it would happen in the live system.
We use Intellij 2017 as IDE and I currently have no idea if or how we could "connect" the bytecode to either the strings which is was generated from, or the copied groovy classes we use for unit testing.
Any other tool that would allow us to debug would be fine as well.
I am working on a project aims to make software reuse easier. The final project provides a framework to select a desired feature from a (Java, C++) program and adds that to the another program.
I am responsible for two parts of the project.
Fixing possible compiler errors after the desired feature is added to the another program.
Changing the desired feature to be usable in its new location. In this case the program should pass successfully all test cases (not details at the moment as my question is related to Section 1).
Currently, I implemented the first step and the program can automatically fix possible compiler errors after the desired feature is added to its new location. It almost supports all Java compiler errors (even that some of them never happen in the above project), and in few of cases a user needs to help the plugin to fix the compiler error.
Note that the plugin has access to both programs and using these information it will fix compiler errors.
For clarity, as a very simple example in a case that there is a dependency between the desired feature with a library in its original location, the plugin tries to fix the compiler error for example by adding that library to the program.
I know current IDEs provide suggestions in a case that there is a compiler error in the program, but the advantage of the current plugin is that it automatically can fix compiler errors, and does not provide a list of solutions to the user for each compiler error.
The question That I am facing is that: Any one could please mention other situations that I can use the implemented automated compiler error fixing plugin? (of course except the above project). Any suggestion is welcome as it helps me to see other directions of the project.
This question is related to, but not a duplicate of, this question.
My issue is slightly different; I have a "utility module", shared between the client and server code, and it contains no GWT-specific code.
I understand that normally, all the sources are pulled into one specific project, where everything is compiled together. But there is one issue with that: I only get to know if my utility project is "GWT compatible", when I compile the main project. This is way too late; I haven't even got around to start on the main project, but I want to know before I make a "commit" to my SCM, that my utility project is "GWT compatible".
In other words, I want to validate the utility project for GWT compatibility, independently from it's use in a separate project (module).
There's a large part of the JRE that is not covered by GWT, and it is particularly likely in a utility module that non-GWT-compatible classes or method be used. That is what I want to validate against.
EDIT: I could add a "dummy entry point", I suppose, but that makes the project depend on GWT, which I don't want to, since it is "general" code, also to be used by people that don't use GWT. If it matters, I use Maven as build system.
EDIT2: No matter what I do, I will only get real compilation/validation with an entry point (does NOT need to reference any of the classes). Neither <force>true</force>, nor <failOnError>true</failOnError> will do. Is there a way I can define that entry point, for the shared project, such that only gwt-maven-plugin sees it, but not javac (so as not to add an unneeded dependency in the Java code)?
The compiler actually always visits all code on the source path (note: not quite the same as the classpath), by starting at the requested module with any <source> tags, and then checking each <inherits> along the way. If it finds something that isn't compatible or isn't compilable, it will mark it as broken, and move on - as long as nothing actually depends on it (i.e. an EntryPoint, or something that an EntryPoint depends on) you'll just see this message:
Validating newly compiled units
Ignored 1 unit with compilation errors in first pass.
Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
If you include that -strict flag, the compile will actually fail when it hits something that can't be included correctly.
This work is done in the very early stages of the compile, while constructing the TypeOracle, which is used for Generators, long before any JS is built. That type oracle is passed to generators, which need to be able to ask questions like 'what interfaces on the sourcepath have a JSO implementation' and 'what are all possible subclasses of List'. Generators can do a huge number of things, including emit even more types which then need to be parsed, compiled, and the process continues until a full JProgram is created of all possible types, based on the current set of modules.
That JProgram then gets compiled down based on what can be reached from the roots - the entrypoint, as well as a few other details such as how to emulate Java details like casts, arrays, longs, exceptions, etc.
If -strict was not specified, and the compiler ends up needing to reach something which is unavailable due to earlier compilation problems, that is the time you find out. Using -strict to stop earlier will help ensure that you catch those issues sooner.
One more fun fact: By default, with com.google.gwt.user.User in your module (or any other <inherits> that depends on it), you already have an entrypoint, or several! These do some quick checking that your page is working correctly, such as using a strict doctype, or the browser actually matching the expected user.agent setting. This means that it is usually possible to compile a module even without an entrypoint (except with gwt-maven-plugin:compile, which will not consider a module for compilation just by those built-in ones).
EDIT: Okay, even one more: From http://www.gwtproject.org/doc/latest/DevGuideCompilingAndDebugging.html, combined with -strict, it looks like you can force the validation to run without actually compiling to JS:
-validateOnly Validate all source code, but do not compile
I don't think it's possible because the GWT compiler does not compile any unused code.
This means that your shared utility "module" may have code in it that is not compatible with GWT, but it will not cause any problems as long as GWT code never calls such incompatible classes or methods. Without an entry point GWT compiler won't know which code is used and which is not - it will assume that all of it is unused.
Is there a way to run Google Web Toolkit compiler directly from Java code to compile the source code made on the fly? In the same manner as javax.tools for example.
GWT compiles all sources at once, because it compiles the result in one file and performs a lot of optimizations, like leaving out methods not used and inline methods to minimize the total size of the JavaScript file generated. A compilation step is therefor takes some time, so compilation on the fly would not be a workable solution.
I think so: com.google.gwt.dev.Compiler has a main method. Either call that method directly, or look into its code, and you should be able to build the CompilerOptions etc. yourself.
When you create a GWT project using webAppCreator, you get a build.xml with a gwtc target. This should help you with the classpath and the arguments you need to run the compiler.
And what are the pro's con's of using either?
I actually saw it in Netbeans under Project Properties > Libraries for Java Applications. We have two tabs, one for compile time libraries and run time libraries, and it looks like we can add a library to either independent of each other
There is no such a thing as compile time libraries vs. runtime libraries
Perhaps you're mixing some concepts.
In Java the libraries to be used are statically validated at compile time and also validated at runtime.
For instance if you want to use IterableMap specified in the Apache Collections library. The compiler validates "at compile time" you are invoking a method that exist in that class.
But the compiler doesn't link or do much of anything with that library, you still need it at runtime. So, when your code executes, the Java runtime, searches for that class again, and invokes the method the compiler verified existed.
And that what there is.
The UI and terminology of the Libraries properties dialog is pretty confusing.
The Help button on that dialog will give you a fair bit of info.
The Compile-time library list may be a subset of the Run-time library list.
Consider this situation...
You have source code that imports classes from on a library 'widgets.jar'. The class files in widgets.jar reference symbols from the jar file 'xml.jar'. If your source code does not import classes from xml.jar, you could define the Compile-time libraries list to contain just widgets.jar.
When you try to run your project, you will probably need to include xml.jar in the Run-time libraries list to prevent ClassNotFoundException's.
Perhaps, this comes into play when you want to load a library dynamically, or check for an existence of the library and then execute the code.
During compilation, compiler needs to know what the signatures of the methods, classes etc to know if you code is correct. Hence you add the compile time library.
During runtime, JVM still needs the library to run that specific code. But you can put a logic to avoid that code by checking if the library exists, for example by doing Class.for() method. Some libraries might already exist in the system (qt.jar for example) or might not, and you can check and execute your code accordingly.
Please correct me if I am wrong.
As others have stated, you are confusing concepts. I think what you are really trying to understand is what Maven refers to as dependency scope. Sometimes you only need a dependency at compile time because you expect it to be provided at runtime, and sometimes you need it at runtime but not compile time.