Inherit .sbt files - scala

I have many small Scala applications and I would like a central place to manage versions of common dependencies.
I know I can set up a Build.scala file and define multiple projects. I used to have that, but not all of these applications are related in that sense. They just happen to share a common software architecture.
How do I achieve this with SBT? Currently I'm managing multiple .sbt files that I batch update (like dependencies.sbt, common.sbt etc.).
My initial approach was to start writing a plugin, but I got stumped along the way with getting dependencies working within the plugin.
I wanted to collect plugin settings and build settings. But I never got one plugin to depend on a set of other plugins.
Anyone tried this before, how do I manage central application profiles (both plugins and settings)?

Do you mean different applications? You can then just put your settings into global.sbt. You can look for more detailed description here

Related

Recommended way of placing dependent jars in ContentNavigator

we have some dependent/common jars of the plugin which we are currently placing in .lib of ContentNavigator application and referring the same in build.xml of ContentNavigator. while we placed the jars in local and tried to give the local path in build.xml it didn't worked out.Can anyone suggest what is the recommended way of doing it?
I've applied the following approaches:
Embed/extract all the content(.class files) of the dependency-jars within the navigator plugin. While the upside is that you have a nice bundle containing all your dependency-classes, it might cause some problems with signed jar's. Or on files that are duplicate amongst your dependencies.
Make use of the "Shared Library" concept. You basically "attach" jar's to the classloader of your server/JVM, Application(ear) or module(war). In your case you would probably attach the shared-library to the navigator.ear, allowing all plugins to access the dependencies you register as a sharedlibrary. One huge downside is (in my experience) that you need to reboot websphere every time you update one of the library-jars.
A third option is to move the functionality out of your ICN Plugin, and let another EAR/EJB do the work (and reference to it from the plugin using a jndi lookup).
I personally prefer option 3 because it's the cleanest way to bundle your functionality&dependencies in an EAR. But option 2 will be a good call when libraries are truely common and won't be updated often.
p.s. In your question you mention the build aspect of your software as well (e.g. "how to correctly reference the dependencies"). You might want to look into the concepts of "dependency management" (using Ant, IVY is a good choice, but i would suggest moving to Maven, or Gradle)

Architecture for plugins to be loaded in runtime

Considering that I am developing an end-user software program (as an uberjar) I am wondering what my options are to make it possible for the user to download a plugin and load that during runtime.
The plugin(s) should come compiled and without source code, so sth. like load is not an option.
What existing libraries (or ways of Java...?) exist to build this on?
EDIT: If you are not sure I would also be satisfied with a way that costs a reboot/-start of the main-program. However, what is important is that the source-code won't be included in any JAR file (neither main application nor plugin-jars, see :omit-source of Leiningen documentation).
To add a jar during runtime, use pomegranate which lets you add a .jar file to the classpath. Plugins of your software should be regular Clojure libs that follow certain conventions that you need to establish:
Make them provide (e. g. in an edn) a symbol to an object implementing a constructor/destructor mechanism such as the Lifecycle protocol in Stuart Sierras component library. In runtime, require and resolve that symbol, start the resulting object and hand it over to rest your programs plugin coordination facilities.
Provide a public API in your program that allows the plugins to interact with it in ways that you coordinate asynchronously e. g. with clojure.core.async (don't let one plugin block the entire program).
Make sure that the plugins have a coordinated way to expose their functionality to each other only if they desire so to enable a high degree of modularity among your plugins. Make sure that your plugin loader is capable of detecting dependencies among plugins and is capable of loading and unloading them in the right order.
I've not tried it myself, but you should in theory be able to get OSGi to work with Clojure.
There's a Clojure / OSGi integration library here:
https://github.com/aav/clojure.osgi
If I were to attempt to role my own solution, I would try using tools.namespace to load and unload plugins. I'm not entirely sure it will work, but it's certainly in the right direction. I think one key piece is that the plugin jars will have to be "installed" in a location that's already on the classpath.
Again, this is only the start of one possible solution. I haven't tried doing this.

How to create several flash application sharing common codebase in FlashDevelop/ActionScript 3.0?

Situation:
I need several swf/exe output files compiled in FlashDevelop from several projects. More than 60% of ActionScript 3.0 source is common for all project, rest are project-specific. How can I organize that in FlashDevelop? I want to have "one-click-to-build all" setting without duplicating common codebase (so when I need to fix something I do not need to copy-paste solution into several files).
All sources are under develeopment and will change very often.
A straightforward solution is to make an external classpath, for instance:
c:\dev\shared_src\
c:\dev\project1\
c:\dev\project2\
Then configure each project:
Project Properties > Classpath
Add Classpath > select '../shared_src'
PS: of course you should keep everything under source control.
Using svn:externals you could structure your repository in such a way that the commom parts are stored just once in the source control system, so changes made can be synchronised with just a single commit and update cycle.
For example, imagine that you have ^/ProjectA and ^/ProjectB, each of with require ^/Common as a sub directory.
Using svn:externals, pull ^/Common into both projects.
The exact nature of doing this will depend on the version of svn you use, and any client you use (such as TortoiseSvn). Refer to the relevant edition of the svn book for specifics.
The ease of implementing this will depend quite a lot on how separate the common code currently is in your application; and pulling in directories as directories is much more practical than trying to pull them into an existing directory; and unfortunately wildcards for filepaths are not supported.
However, based on your description of your aim; this is the most straight-forward solution I can imagine.
Hope this helps.

How best to structure and build Clojure apps with plugins?

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.

PDE Build cannot resolve classes in plugins it depends on

Working Eclipse features and plugins, I have a problem with building two separate features (lets call them One and Two) where Two contains plugins that depend on plugins in One. I use PDE Build and ideally would like to have the option to build just One or Two (assuming One was built at some previous point in time).
However, having built One and then trying to build Two I run into the problem that classes that were built in One cannot be resolved. I am trying to get the second build to use the .jar files which were the output of building One, but have had no success. It simply seems it ignores the build output from One.
I've tried various solutions, like using build.properties pluginPath property to refer to the .jar files I depend on. Copying the already built plugins into buildDirectory is not a good option either, since the environment I am working in is a bit messed up and the build directory also contains other plugins that are not to be built (including the plugins built with One).
Any suggestions are welcome!
Cheers,
Anders
In PDE, features are just sets of plugins. This is meaningful during installation but not during build. So you can't say "plugin X depends on feature Y", you can only say "plugin X depends on plugin Z"
So what you need to do is this:
Add dependencies to the plugins in Two which mention the plugins from One
Add One to the "target platform definition". This is basically a list of plugins which will be available when the plugins of Two will be installed at some time in the future.
This blog post should get you started how to create your own target platform.
[EDIT] These two blog posts might also be useful:
http://pweclipse.blogspot.com/2011/02/pde-build-as-workspace-export.html
http://www.vogella.de/articles/EclipsePDEBuild/article.html