According to this post In order to create a Scala compiler plugin, one needs to compile the plugin into a jar, and then either specify the reference to the the jar as command line arguments, or place the jar in $SCALA_HOME/misc/scala-devel/plugins.
I need to call the compiler in runtime, with the scala compiler API (scala.tools.nsc).
Is it possible to Is it possible to the compiler plugin dynamically in runtime, before calling the compiler?
I am not entirely sure what you mean by loading it in runtime, but I assume you intend to also call the compiler at runtime then and supply it with that plugin.
In that case, yes this is possible. You can take a look at RunPlugin.scala from the alacs test suite for an example. The project's not really active anymore, but it provided compiler plugins for additional checks, which are also tested via a test suite involving the above class for runtime compilation with selected plugins.
Related
The Jetbrains Kotlin compiler in Eclipse outputs to a hidden folder inside the Eclipse compiler plugin. This hidden folder is then made available through the Eclipse Kotlin classpath container.
In bndtools we need a normal file system folder since bnd can run both from the file system as well as in Eclipse. Since the folder is a linked resource there is no known way to translate it outside Eclipse.
Anybody knows how to tell the Kotlin compiler to just output it in the bin folder?
Currently, this is not possible in the Kotlin Eclipse plugin.
To make it possible that Kotlin code can be used from Java, Kotlin plugin produce so-called lightweight class files to this folder. These class files do not contain bodies for methods and they are stored in memory.
Actual class files, that are used to run an application, are being built only before launch and they are produced to the default output folder. For now, we cannot produce class files on each save reasonably fast as there is no incremental compilation in the plugin yet:
Feel free to upvote for this issue.
From the short analysis of the code of Kotlin plugin, it looks like the proper method is KotlinCompiler.compileKotlinFiles. It is being called in two contexts:
KotlinBuilder.build — this is the one called on the project build; it makes a call stack trick (or rather a hack...) to check if being called from the LaunchConfigurationDelegate, and depending on the results, either compiles whole project (via its own private fun compileKotlinFiles), or just makes stubs in memory.
KotlinCompilerUtils.compileWholeProject — this is in fact being called from 1.; nice static method, perfect for abuse until the problem is correctly solved in the plugin. :)
So, I'd use the method from 2. wrapped in a similar way as compileKotlinFiles from file in 1.
I have run into a compilation error:
[warn] Class com.google.api.client.auth.oauth2.Credential not found - continuing with a stub.
[error] error while loading GoogleService, class file '....../gdata-core-1.0.jar(com/google/gdata/client/GoogleService.class)' is broken
I found this similar question but couldn't successfully use its solution for my case. How can I trace what's actually broken in this jar as per the Scala compiler (i.e. get the details of what's actually broken), to make sure what the solution aught to be?
The source where I think this Google jar builds from, is here.
Note: unlike the other questions, in my case, the google jars are included unmanaged in my project, in the lib directory, as per these google setup instructions.
As described in your linked answer, this error happens when a class contains some annotations which are no longer present on the classpath. Java considers this acceptable, but Scala does not. You'll generally only run into this problem with heavily optimized java libraries where they've deliberately excluded the "unnecessary" annotations. Google does this for a lot of their code; to be perfectly honest I don't think I've ever seen the problem in any non-google libraries.
The pragmatic solution is to use advanced search on maven central to find the jar that contains the missing class. If gdata-core had been built with maven (as most serious java libraries are these days), it would be easy to see from the <dependencies> section of pom.xml which dependencies had been declared optional, and therefore figure out where any classpath problems of this kind were likely to be. Unfortunately this particular library is still built with ant, so it's hard to determine the build classpath without reading the whole build.xml and figuring it out "by hand".
Had to find a google supplied jar file where the class mentioned in the warning (class Credential) is contained, and stick it in my lib directory used by sbt.
With really a lot of heuristic, it turned out to be the jar file google-oauth-client-1.18.0-rc.jar which I obtained here and equally exists here, after figuring that the source file that the error is for, simply does not define that class itself but rather imports it from a different package com.google.api.client.auth.oauth2. I guess the latter package must have been present at compile time, and its compiled class is necessary for Scala being able to use the classes contained in the former jar, at least when Scala is involved.
Not exactly sure how the build system at google produced all of this, and how to pin down the annotations that made the additional jar required for Scala, but the missing class is no longer missing for Scala.
Hope someone would chime in to provide a deeper answer, as to how to pin down the details of a class being broken for scala, and how to trace back where to obtain it sans my heuristic search.
I'd like to write a plugin that makes its code available to projects that uses the plugin.
The plugin would be defined as follows:
package mypackage
object MyPlugin extends sbt.Plugin {
...
}
trait MyInterface {
...
}
A client code should be able to export and instantiate mypackage.MyInterface to make possible for plugin distinguish MyInterface instances during parsing Analysis API info.
I should add that I would like to create separate config for doing some code testing (existing test are not suited for me) and plugin would be exported only to this config's classpath.
If someone would like to ask if this approach is legitimate I answer that sbt itself uses this method for working with plugins. I've found almost no documentations for writing sbt plugins and was forced to peek inside the sbt code. There I found similar cases and some hints. But the code is too complicated full of macroses and DSL with lack of documentation strings, so I grasp only part of it.
My rather limited knowledge about sbt lets me argue about the merits of your question and what you're going to achieve.
Since a plugin is a part of the build and should (merely) help the project's artifact(s) see the light of production release, it should in no way be the artifact's dependency as you'd have to release the dependency (that's a sbt plugin in its current form) so others would be able to download it, too.
What you'd rather do is to have a plugin that wraps a dependency and when included in a build makes the dependency a dependency of your project. That's acceptable in my opinion.
How much do I differ from your use case? I'd happy to refine the answer after having heard some additional information.
Ie. I have a GUI package, and a Logic package.
How can I prevent the Logic classes from importing GUI classes? Others(or myself) working on the same project might do that, which I want to prevent.
A solution could for example be a check in JUnit, that fails if its done, or a runtime check that throws an exception. Something along these lines, but how to do it?
You can write such a test using JDepend or DependencyFinder or Degraph.
Degraph is the only of the three tools that explicitly is intended to actually write tests for cases like this. Also AFAIK JDepend does not find all dependencies in more recent Java Versions (like classes mentioned in Annotations).
I'm the author of Degraph so I'm obivously biased.
I created the JabSaw project. It allows you to define modules by using annotated classes and to express the relationships between the modules. By default, a module contains all classes in a single package.The restrictions can be checked using a Maven plugin, from the command line or from a unit test. This should solve your problem.
One solution which comes to my mind is make GUI classes package private. Although you cannot isolate only one package and say, only Logic classes cannot use GUI, but other can.
I recently integrated gwt-log into my GWT and Maven based project mostly because of it's ability to automatically deobfuscate client side stack traces on the server. To make this possible gwt-log needs a so called symbol-map which maps all of the obfuscated symbol names to the original Java symbol names. The GWT compiler is capable of generating these symbol maps but for some reason they are saved to a strange location, eg.:
target/project-name-1.0-SNAPSHOT/project-name/.junit_symbolMaps/0F9FD6EF6A1BC63EA834AC33C7ED13F3.symbolMap
According to the GWT Maven Plugin Documentation the GWT compiler has a "-deploy" parameter which determines where to create files like that and which per default points to "WEB-INF/deploy". But even if I manually set this parameter to the correct location the compiler still creates the symbol-maps in the wrong folder.
I even downloaded the GWT Maven Plugin sources and added some log output to find out whether or not the "-deploy" parameter is passed correctly to the compiler but all seems fine.
Has anybody experienced a similar behavior?
Thanks!
Michael
Disable JUnit GWT Module.
http://groups.google.com/group/google-web-toolkit/browse_thread/thread/552a9578a76587ae#