Background
I'm a developer of the Vrapper project.
Vrapper contains of 2 major parts
Vim-emulation library (vrapper.core)
Eclipse part that makes a good use of it
We want vrapper.core to be Eclipse-unaware, so it's reusable
outside of the Eclipse. Currently, we can "vrap" all sorts of Eclipse
text editors and our little mock text editor that we use for unit testing.
vrapper.core implements all sorts of Vim commands, modes, etc.
Those all communicate with Platform - an interface that abstracts out
underlying stuff (text editor, clipboards, settings system, etc.).
When mode is created for an editor it asks platform if there are extra
commands that are approperiate for underlying editor, currently edited file type, etc.
EclipsePlatform provides those commands using Eclipse extension points mechanism.
So, let's consider the following projects (there are more):
vrapper.core - Eclipse-independent code for Vrapper
vrapper.eclipse - Eclipse plug-in that depends on vrapper.core
surround.core - Eclipse-independent code that emulates surround.vim (Vim plug-in)
surround.eclipse - Eclipse fragment for vrapper.eclipse
that makes it provide commands form surround.core.
There are two ways we can deal with those:
One plug-in to rule them all
This is how it should look like from Eclipse's perspective.
There is one plug-in that contains code from vrapper.eclipse and vrapper.core,
and one fragment that contains code from surround.core and surround.eclipse.
Many plug-ins
There are 3 plug-ins
two OSGified libraries vrapper.core, surround.core
vrapper.eclipse
surround.eclipse fragment depends on vrapper.core in this case
Problems
Many plug-ins solution have some issues with lazy class loading that I don't understand.
It's beacause when instances of modes from vrapper.core are created they need
classes from surround.core to be created (via vrapper.eclipse -> surround.eclipse).
This works if you run stuff from Eclipse and select all plug-ins from run configuration,
but if one deploys features & plugins and run eclipse normally an exception is thrown
because classes from surround.core cannot be found.
It's something in the spirit of surround.core asking for extra commands from
dependent plug-ins creates implicit circular dependencies.
What I mean by implicit dependencies is that no core class depends on eclipse-specific classes in compile time.
Modes (like vim normal mode) are core classes. They contain commands. There are some commands specific for particular Eclipse editors (like run this JDT-specific refactoring). Those commands implement core interfaces, but their code (obviously) lives in eclipse-specific projects. When mode is created it asks underlying platform for some extra commands - those extra commands are implemented in eclipse plug-ins. This is when lazy class loading in eclipse make everything blow up in runtime - classes for extra commands are referenced by extension points, but they are not yet loaded. Boom, exception.
I tried to work this around by using "one plug-in to rule them all" approach.
Having just one plug-in seems to be much better solution to me, but I couldn't make it work cleanly.
Only thing that succeeded for me was quite an ugly hack.
All .core projects had an Ant task that created .jar file with their classes
and dropped it into corresponding *.eclipse project
*.eclipse projects included that jars and had them enlisted in MANIFEST files.
The problem with this ugly hack approach (besides of it being ugly hack) is
that development becomes quite painful. Eclipse code navigation, code coverage
and few other things in Eclipse stops working.
Summary
We have eclipse independent library + eclipse specific stuff architecture,
but we really need all of this to live in one plug-in (because there are some dependencies in both directions).
How do I make code from few projects live into one plug-in/fragment?
It turned out that adding Eclipse-BuddyPolicy: dependent to MANIFEST.MF files, reexporting some dependencies and turning one fragment into plugin (so there is plug-in dependency for BuddyPolicy to track) was the right solution.
Problem solved :-)
From reading this it sounds as if the actual problem is the fact that there are dependencies in both directions. Can't you refactor your projects to make only the Eclipse-spcific proejcts depend on the core projects, and not the other way around?
Related
I would like to know if there is a way to organize multiple DSLs inside a single Eclipse project. More specifically, I would like to organize all five Xtext projects of a DSL in some top-level "project folder".
The background is that we manage complexity and enable reuse by making smaller reusable DSLs, e.g. one reusable for expressions and other one for more domain-specific or application-specific aspects. However, each Xtext DSL results in 5 projects, causing a lot of clutter in the Package Explorer when multiple DSLs are involved. A strongly related question has been asked before:
Xtext: define 2 DSL's in one project
The answer there is that multiple DSLs are not needed inside the project for that specific use-case. My use-case is different because I want to be able to easily view the different DSLs and potentially co-develop them.
We are using Xtext in an environment managed by Gradle. We are using the Gradle Eclipse plugin, which creates a lot of Eclipse project files everywhere. As a result, when choosing to "Open Project from File System" in Eclipse, I not only get the option to import the five projects related to the DSL, but also the option of opening the parent folder as a project. This means I can have each DSL (all its five projects) organized neatly in a "project folder". This is exactly what I want! ...
BUT ...
it does not actually work. The figure below shows my package explorer with the five projects of my ExperimentDSL included in the bottom. This DSL works. On top, it shows the folder structure I get when including the project file generated by Gradle, resulting in a "project folder" that can potentially contain multiple DSLs.
As you can see, GenerateExperimentDSL is flagged red and refuses to run. It seems Eclipse somehow treats it as a Java project, but I do not know how to change this or and if this would help solve my problem. Secondly, I would not know how to set up such a project by hand, since the project file in this failing case was generated by Gradle.
Long story short, does anyone know how to get this kind of folder structure to work so that I can keep all my DSLs in the workspace without clutter?
What you try to do is currently not possible. Have a look at the concept of WorkingSets in Eclipse that let you achieve something similar
I have seen, read and thought of different ways of using Workspaces (per project, per application (multi-asseted or not), per program language, per target (web-development, plugins,..), and so on) and I am still doubting what the best approach is.
Can anyone give a detailed, but not a page long insight into this?
This involves a lot of sub-questions, so to speak, and I don't know all the specific sub-questions I should ask, as I am sure I don't know all aspects of Eclipse (and Workspaces), but I'll try to give an example of what I am looking for:
What for?
What did the Eclipse development team expect it to be used for?
What do other/most people think?
What do you think?
... ?
Why?
Are there configuration conflicts vs. sharing merits?
Any filespace reasons?
Performance?
... ?
I am speaking of the minimum use-case for a developer that uses different languages and protocols, not necessarily all of them in one project (E.g. Php, Javascript and XML for some projects, C# for others, Java and SQL for still others, etc..)
Edit 2012-11-27: Don't get me wrong. I don't doubt the use of
Workspaces, I just want to use it as it is meant to be or otherwise if
anyone would think it better. So "what for?" means: What's the best use? And
"why?" actually targets on the "what for?", in other words: tell me the reasons
for your answer.
I'll provide you with my vision of somebody who feels very uncomfortable in the Java world, which I assume is also your case.
What it is
A workspace is a concept of grouping together:
a set of (somehow) related projects
some configuration pertaining to all these projects
some settings for Eclipse itself
This happens by creating a directory and putting inside it (you don't have to do it, it's done for you) files that manage to tell Eclipse these information. All you have to do explicitly is to select the folder where these files will be placed. And this folder doesn't need to be the same where you put your source code - preferentially it won't be.
Exploring each item above:
a set of (somehow) related projects
Eclipse seems to always be opened in association with a particular workspace, i.e., if you are in a workspace A and decide to switch to workspace B (File > Switch Workspaces), Eclipse will close itself and reopen. All projects that were associated with workspace A (and were appearing in the Project Explorer) won't appear anymore and projects associated with workspace B will now appear. So it seems that a project, to be open in Eclipse, MUST be associated to a workspace.
Notice that this doesn't mean that the project source code must be inside the workspace. The workspace will, somehow, have a relation to the physical path of your projects in your disk (anybody knows how? I've looked inside the workspace searching for some file pointing to the projects paths, without success).
This way, a project can be inside more than 1 workspace at a time. So it seems good to keep your workspace and your source code separated.
some configuration pertaining to all these projects
I heard that something, like the Java compiler version (like 1.7, e.g - I don't know if 'version' is the word here), is a workspace-level configuration. If you have several projects inside your workspace, and compile them inside of Eclipse, all of them will be compiled with the same Java compiler.
some settings for Eclipse itself
Some things like your key bindings are stored at a workspace-level, also. So, if you define that ctrl+tab will switch tabs in a smart way (not stacking them), this will only be bound to your current workspace. If you want to use the same key binding in another workspace (and I think you want!), it seems that you have to export/import them between workspaces (if that's true, this IDE was built over some really strange premises). Here is a link on this.
It also seems that workspaces are not necessarily compatible between different Eclipse versions. This article suggests that you name your workspaces containing the name of the Eclipse version.
And, more important, once you pick a folder to be your workspace, don't touch any file inside there or you are in for some trouble.
How I think is a good way to use it
(actually, as I'm writing this, I don't know how to use this in a good way, that's why I was looking for an answer – that I'm trying to assemble here)
Create a folder for your projects:
/projects
Create a folder for each project and group the projects' sub-projects inside of it:
/projects/proj1/subproj1_1
/projects/proj1/subproj1_2
/projects/proj2/subproj2_1
Create a separate folder for your workspaces:
/eclipse-workspaces
Create workspaces for your projects:
/eclipse-workspaces/proj1
/eclipse-workspaces/proj2
The whole point of a workspace is to group a set of related projects together that usually make up an application. The workspace framework comes down to the eclipse.core.resources plugin and it naturally by design makes sense.
Projects have natures, builders are attached to specific projects and as you change resources in one project you can see in real time compile or other issues in projects that are in the same workspace. So the strategy I suggest is have different workspaces for different projects you work on but without a workspace in eclipse there would be no concept of a collection of projects and configurations and after all it's an IDE tool.
If that does not make sense ask how Net Beans or Visual Studio addresses this? It's the same theme. Maven is a good example, checking out a group of related maven projects into a workspace lets you develop and see errors in real time. If not a workspace what else would you suggest? An RCP application can be a different beast depending on what its used for but in the true IDE sense I don't know what would be a better solution than a workspace or context of projects. Just my thoughts. - Duncan
Basically the scope of workspace(s) is divided in two points.
First point (and primary) is the eclipse it self and is related with the settings and metadata configurations (plugin ctr). Each time you create a project, eclipse collects all the configurations and stores them on that workspace and if somehow in the same workspace a conflicting project is present you might loose some functionality or even stability of eclipse it self.
And second (secondary) the point of development strategy one can adopt.
Once the primary scope is met (and mastered) and there's need for further adjustments regarding project relations (as libraries, perspectives ctr) then initiate separate workspace(s) could be appropriate based on development habits or possible language/frameworks "behaviors".
DLTK for examples is a beast that should be contained in a separate cage.
Lots of complains at forums for it stopped working (properly or not at all) and suggested solution was to clean the settings of the equivalent plugin from the current workspace.
Personally, I found myself lean more to language distinction when it comes to separate workspaces which is relevant to known issues that comes with the current state of the plugins are used. Preferably I keep them in the minimum numbers as this is leads to less frustration when the projects are become... plenty and version control is not the only version you keep your projects.
Finally, loading speed and performance is an issue that might come up if lots of (unnecessary) plugins are loaded due to presents of irrelevant projects.
Bottom line; there is no one solution to every one, no master blue print that solves the issue. It's something that grows with experience,
Less is more though!
Although I've used Eclipse for years, this "answer" is only conjecture (which I'm going to try tonight). If it gets down-voted out of existence, then obviously I'm wrong.
Oracle relies on CMake to generate a Visual Studio "Solution" for their MySQL Connector C source code. Within the Solution are "Projects" that can be compiled individually or collectively (by the Solution). Each Project has its own makefile, compiling its portion of the Solution with settings that are different than the other Projects.
Similarly, I'm hoping an Eclipse Workspace can hold my related makefile Projects (Eclipse), with a master Project whose dependencies compile the various unique-makefile Projects as pre-requesites to building its "Solution". (My folder structure would be as #Rafael describes).
So I'm hoping a good way to use Workspaces is to emulate Visual Studio's ability to combine dissimilar Projects into a Solution.
It's just a feature for structuring projects.
Obviously Eclipse designers tried to avoid having global settings for Eclipse and decided to put them into workspace.
Each Eclipse app depends on each workspace settings.
Is it a good decision? I think it's not so.
It lacks flexibility. It was naive to expect that global settings can be avoided.
It doesn't allow you to have single projects (it can be a surprise for Eclipse designers but it happens quite often).
But it still works.
Many people use it. Sometimes they suffer but more frequently everything is ok.
I think (see below) that I would like to structure a Clojure project as multiple modules, with ordered dependencies - just like Maven lets me do with multi-modules projects.
But I can't see how to do this with Leiningen - all I can see is the checkouts fix described in the FAQ which doesn't seem to be as powerful.
Will lein do this? Should I be using Gradle instead? Or is this kind of thing not needed?
Some more context: I am wondering how to architect a modular application that supports plugins (which I imagine means jars dumped on the classpath). And am wondering to what extent I can structure that as a core + plugins (I am thinking I should be able to do something with Clojure's dynamic code loading and not have to go with Java/OSGi). So I guess the driving motivation for a single project comes from wanting some way of packaging everything (the core + default plugins) as a single blob that is easy for the end user, but which can also be divided up (and which is built and tested in fragments, testing the logical independence of each module). More general advice about this is welcome
Update
A possible solution that wasn't mentioned below is using a Maven plugin - I assume that supports everything Maven does, but compiles Clojure, so will work with nested modules, etc.
First, it does not seem like Leiningen supports a module hierarchy like Maven does. The checkouts are the next closest thing it has. It should be sufficient though to develop a modular application in Clojure though.
For the project structure, I would have an API project, a "core" project, the plugins themselves, and a separate packaging project. The core and the plugins should only depend on the API. Which build tool you use to create the packaging project is up to you. Gradle would probably be more effective at handling the packaging, however having the "checkout" functionality Leiningen offers could make development of the system as a whole easier.
I would take a look at the code for Leiningen and Noir to figure out how to effectively handle this.
For dynamically loading the plugins, I would start with looking how Noir handles it in two of their files:
server.clj has namespace loading for all files under a particular namespace. Under the hood it uses tools.namespace, but you can easily see how it's used to require every namespace under a particular base. This is how Leiningen handles custom tasks as well - the base definition for the task should be in the leiningen.$task namespace.
core.clj has what I would use for plugin registration. In summary, use a map under an atom and add plugins to that map. I would advice wrapping the registration with a macro to keep your code cleaner.
What I listed above should be sufficient if you don't need to handle adding plugins at run time. If you don't have every plugin on the classpath during start-up, I would recommend utilizing pomegranite to add entries to the classpath. You can see an example in classpath.clj.
I was wondering if there is a way to develop Eclipse plugins in Clojure. To be clear, the question is not about using Eclipse to write Clojure code.
Both Eclipse and Clojure run on the JVM and I feel there should be way to leverage the power of Clojure (and it's libraries) to develop plugins. I was specifically looking at using Korma, but overall I would like to move complete plug-ins to clojure if there is a natural way to do it.
Counterclockwise, the Eclipse plugin for Clojure, is written in mixed Java and Clojure. It uses clojure.osgi 1.2.10 yet.
So it is a live proof of concept that it is possible. And AFAIK, Counterclockwise is used successfully by hundreds of people.
There are some constraints, tho: Clojure's namespace is "global" to some "root classloader". E.G. if you package Clojure inside a bundle named, say, myapp.clojure, then you'll probably have a bunch of other bundles which will require myapp.clojure. Say for example myapp.bundle1, myapp.bundle2. When you do so, and, from each bundle, load in memory (require) the bundles namespaces, each one will be loaded from within the right ClassLoader (namespaces of myapp.bundle1 will be loaded within the context classloader of myapp.bundle1, and namespaces of myapp.bundle2 will be loaded within the context classloader of myapp.bundle2). This is great, because it allows java interop to work okay.
But just remember that in the end, namespaces loaded from bundle1 & bundle2 will be held by the "global namespace world" in bundle myapp.clojure.
To be honest, this has not yet proven a problem for Counterclockwise. Because inside the same Feature, having the bundles share one single Clojure instance is almost okay.
The potential drawbacks are:
if you use third party libraries, e.g. tools.logging, you will not be able to have namespaces in myapp.bundle1 depend on version X of tools.logging, and at the same time have myapp.bundle2 depend on version Y of tools.logging. That is, inside your feature where you have a shared clojure via bundle myapp.clojure, you work as if OSGi rules did not apply, as webapps work, for example.
does not scale well if massively applied: if every Eclipse Feature were to repackage its own version of Clojure, there would be some waste of memory. But this drawback is more theoretical than practical, yet. And this is a problem that can be addressed later, when the need for it emerges.
Note that for an Eclipse RCP Product, as opposed to an Eclipse plugin, these drawbacks vanish.
If you want to see how Counterclockwise has repackaged clojure, and uses clojure.osgi, you can look at its sourcecode:
http://github.com/laurentpetit/ccw.clojure.git
http://github.com/laurentpetit/ccw.git
HTH,
-- Laurent
It seems it's not available in Eclipse 3.x, but is planned for Eclipse 4, as mentioned in http://wiki.eclipse.org/E4/Languages .
There's also a post here on Stack Overflow asking about development of Eclipse plugins in languages other than Java that may have more information that you'd find useful.
It's perfectly possible to write Eclipse plug-ins in Groovy or Scala. Since Clojure produces .class files, it should be no different. However, plugins are normally exported using PDE Build, which only handles Java by default, so you will have to write a customCallback.xml file which can compile Clojure (see http://www.michel-kraemer.com/scala-projects-with-eclipse-pde-build-2 for Scala build).
I'm trying to use Google Protocol Buffers in my project and I'd like to have some tooling support from Eclipse. In particular, I want Eclipse to call protoc every time I make changes to the .proto files and then rebuild all code that depends on the generated code.
I tried to set up a Custom Builder but it keeps bugging me with errors I don't understand, most often it complains that the .proto file is not on the path given by --proto-path, which it should be by all I can tell. Also, because I use ${build_files}, Eclipse passes all changed files to the compiler (instead of those that I have configured to trigger the build).
NetBeans seems to have a protobuf-Plugin, but I can't find one for Eclipse. Is there one?
Theres a protoclipse plugin on googlecode, which is in the initial stages:
http://code.google.com/p/protoclipse/
Not sure if there is a builder, but I did find a plugin for syntax highlighting for protocol buffers.
You can define an external builder on the plugin that invokes an ant task. It is an ugly kludge, but until there is a better solution this may serve your purposes.
In practice, syntax highlighting turned out to not be that important, I hardly edit these files, and they tend to be very small. Maven and the m2eclipse plugin handle the building side of things great.
I recommend using Google's "Protocol Buffers Development Tools". It is a plugin for Eclipse that features automagic regeneration and error checking, among other things. It's available here: http://code.google.com/p/protobuf-dt/ .
While this question is close to other Eclipse plugin for working with protobuf, answers here are different.
Well, yes, if you use maven/gradle to invoke protoc (Protobuf compiler), than you may need no Eclipse plugin at all.
Colorizing editor helps for long file or with many comments. Know there are 2 editor plugins for Eclipse.