Is it possible to use other JVM languages such as Scala and Clojure for developing an IntelliJ IDEA plugin? Or do we have to use Java for this purpose? I could find no pointers on this on web, hence posting the question here.
Yes, it is entirely possible.
Any plugin essentially is a set of extensions for several extension points which IDEA API provides. These extensions are regular java classes implementing predefined interfaces, and these classes are referenced to in the manifest. Also, you can bundle any libraries along with the plugin. So, if your language of choice allows implementing interfaces and finding out resulting class names, then nothing prevents you writing plugins in it.
Related
I am planning on writing a library that will primarily be consumed from Java. However, I would like to write this in Scala. I have read most of the documentation on Java/Scala interop, but it is mostly focused on using existing libraries, rather than best practices to ensure seamless interop when writing libraries.
What are some ways of doing this effectively? Ideally, the consumers would not know the library was written in Scala at all.
Are there any other major libraries that do this?
My current plan is to have an API that exposes everything needed with Scala types/features, then having a smaller layer on top of this that converts to Java types. Are there any issues with this approach?
Is there any reason you would want to do this? It's one thing to write a Scala library that can also be used from Scala, but if you want to target Java specifically it probably just makes sense to use Java to write the library.
Ideally, the consumers would not know the library was written in Scala at all.
The biggest issues with this is going to be transient dependencies. Even if you use no third party libraries from yours, what about the Scala standard library? If your library would be used in a project that wasn't otherwise using Scala, they would need to pull in the entire Scala library as well unless you don't use the standard lib at all in your code.
You are going to want to use Java collections instead of Scala collections, and since that's what your client code will be expecting. You should have no Scala Standard Library classes in your public interface. This also means use Java Functional Interfaces instead of Scala Function Types
Avoid companion objects except for situations where they compile down to static members on a class. Accessing a Scala companion object from Java is cumbersome.
Use Java Bean conventions for getters/setters/case classes instead of the regular Scala properties (I believe Scala has an annotation for this).
As far as existing libraries, the Spark Java API is written in Scala, but Spark is primary build for Scala with some Java support, but maybe worth looking at (especially to see the differences between the Scala and Java apis.
The only concerns I found are needing to included the Scala runtime library, and to append _2.13 to the artifact names.
By publishing via Maven (sbt publishM2), even the Scala library comes automatically to the downstream project.
I'd like to use Kotlin & Scala together in projects, and maybe some other languages, but I've seen no good way of doing it. The only way I thought of was compiling one language and decompiling it into Java to work with the other. Are there any alternatives?
For the sake of completeness and not putting words into someone else's mouth, I wanted to weigh in.
I agree with the last sentence of ziggystar's answer. The right thing to do is to take a component-based approach and not try to combine multiple languages in one component or project.
From a technical perspective, each of the JVM languages has their own compiler. Some, such as Scala's, can compile both Scala and Java files. However, this may or may not be true for other compilers. In order to avoid strange build processes, a good approach would be to use a single language for every built module.
Since you're sticking to JVM languages, every languages can be compiled into a JAR, so you can easily distribute your executable binary as a single JAR file, with all of the components wrapped up inside it. This is the Fat JAR approach (see this question on Stack Overflow, this post on Java Code Geeks).
From a human readability perspective, this should also make your software more easily understood. Not only have you decomposed it into logical building blocks (each component), but someone making modifications only needs to understand the language that the component they are working on is written in and the public interface of the components they need to interact with. There's no mental context switching between languages.
You can use Scala and Java simultaneously, since scalac understands and compiles Java files. The same probably holds for other languages. Problems might arise when using multiple alternative JVM languages, since, e.g., the Kotlin compiler probably can't understand the Scala files and vice versa.
I think the best way would be to split the project into different modules, and use at most one alternative language per module.
What do I mean with module?
With module, I mean a set of source files that gets translated into one (binary) artifact, i.e. a jar file. Under different circumstances I would simply call a "module" a project. Note that a module may depend on other modules on the binary level (e.g. has some jar files as dependencies).
Multi module support in IDEs
I think it should be possible with most major IDEs to work on different modules simultaneously, even if each module uses a different language. Terminology varies across IDEs.
Terminology
For Intellij IDEA, one of my modules is called "module". For Eclipse it would be called "project".
For example, is it possible to have Scala, Java, and Clojure source all compile/build together properly inside the same project? Or, do I have to do them as separate project libraries then used by whatever I pick as the "master" project?
If neither of those, how's everyone else doing it?
Unfortunately, while the Java community seems to be very enthusiastic about polyglot programming, the IDE vendors haven't really kept up. They generally do have plugins for Java, Scala, Clojure, Groovy, Ruby, ECMAScript, Python, C++ projects, but mixing multiple languages in one project is generally not supported.
In Ruby, for example, it is quite common to use Swing as a GUI via JRuby. But if you want to use Matisse, the NetBeans Swing GUI builder you must use a Java project, you cannot use Matisse in a Ruby project. However, if you use a Java project, then you can't have a Ruby main executable, you must have a Java main executable. Also, you don't get Rake support and other things that the Ruby project type supports. (The ugly workaround is to write a Java main executable which creates a JRubyEngine instance by hand, loads the Ruby main executable into it and runs it.)
The Eclipse Scala plugin supports a limited amount of polyglotism, but the hoops that they have to jump through are tremendous. Basically, they use runtime bytecode patching to inject Scala Aspects into the Java Development Tools Eclipse plugin, to get type-driven cross-language refactorings to work. The Groovy plugin does similar things, as does AspectJ (in fact, they originally came up with the idea of using aspect weaving to inject new functionality into JDT). So, all of these plugins allow polyglot programming with themselves and Java. But unfortunately not with each other. (Although several of the maintainers have expressed interest in more closely collaborating.)
In general, I fear that the only solution is new IDEs.
Rather late to answer this question, but the answer is that IntelliJ IDEA does a very fine job on polyglot programming. I recently watched a demo where one of their developers did a mixed-language application in 5 (!) languages.
They manage to do multi-language-aware syntax coloring, refactoring and more. They've obviously sunk some effort into this and are justifiably proud.
I was very happy to note that IDEA is now (partly) open-sourced.
I am about to start developing a small Java desktop app. The app is just an engine for which the user provides Java classes to do the work (translating input to output).
I would like the user to provide actual Java classes as files that can be loaded (and reloaded) on the fly.
For this particular use, is there any reason why Java would be more cumbersome than Groovy or Beanshell? I'm not asking for a comparison of Groovy/Beanshell and Java as there are many. Rather, I want to know if it's easier to dynamically load Groovy or Beanshell classes from files compared to Java.
For Java 1.6, is the JavaCompiler the best way to dynamically load code? I would like to use all language features so I think Janino is out. Also, any problems with reloading?
Note: I have seen this and this, but I'm not sure they answer my question.
JavaCompiler is very versatile, but it entails a minor, potential configuration problem: In javax.tools, ToolProvider.getSystemJavaCompiler() identifies the compiler's class as com.sun.tools.javac.api.JavacTool. On some platforms, that class is not part of the JRE; a JDK appears to be required. Here is an example.
Also consider javax.script, discussed here. Several scripting engines are supported.
I intend to develop a system that is entirely based on modules. The system base should have support for finding out about plugins, starting them up and being able to provide ways for those modules to communicate. Ideally, one should be able to put in new modules and yank out unused modules at will, and modules should be able to use each other's funcionality if it is available.
This system should be used as a basis for simulation systems where a lot of stuff happens in different modules, and other modules might want to do something based on that.
The system I intend to develop is going to be in Java. The way I see it, I intend to have a folder with a subfolder for each module that includes a XML that describes the module with information such as name, maybe which events it might raise, stuff like that. I suppose I might need to write a custom ClassLoader to work this stuff out.
The thing is, I don't know if my idea actually holds any water and, of course, I intend on building a working prototype. However, I never worked on a truly modular system before, and I'm not really sure what is the best way to take on this problem.
Where should I start? Are there common problems and pitfalls that are found while developing this kind of system? How do I make the modules talk with each other while maintaining isolation (i.e, you remove a module and another module that was using it stays sane)? Are there any guides, specifications or articles I can read that could give me some ideas on where to start? It would be better if they were based on Java, but this is not a requirement, as what I'm looking for right now are ideas, not code.
Any feedback is appreciated.
You should definitely look at OSGi. It aims at being the component/plugin mechanism for Java. It allows you to modularize your code (in so-called bundles) and update bundles at runtime. You can also completely hide implementation packages from unwanted access by other bundles, eg. only provide the API.
Eclipse was the first major open-source project to implement and use OSGi, but they didn't fully leverage it (no plugin installations/updates without restarts). If you start from scratch though, it will give you a very good framework for a plugin system.
Apache Felix is a complete open-source implementation (and there are others, such as Eclipse Equinox).
Without getting into great detail, you should be looking at Spring and a familiarization with OSGI or the Eclipse RCP frameworks will also give you some fundamental concepts you will need to keep in mind.
Another option is the ServiceLoader added in Java 1.6.
They are many way to do it but something simple can be by using Reflection. You write in your XML file name of file (that would be a class in reallity). You can than check what type is it and create it back with reflection. The class could have a common Interface that will let you find if the external file/class is really one of your module. Here is some information about Reflexion.
You can also use a precoded framework like this SourceForge onelink text that will give you a first good step to create module/plugin.