-
Notifications
You must be signed in to change notification settings - Fork 62
ceylon assemble #6712
Comments
@quintesse do you think this is something that you might be able to work on Tako? |
I can certainly try :) |
That would be awesome. Let me know if you have questions about what precisely this should do. |
Btw @gavinking you mention "russian doll packaging", does that mean you envision assemblies containing other assemblies? I would have thought the embedding of .car files would only be one level deep? That is, we get all the necessary modules, including system modules and stuff their .car files in a .jar file with some special class loading. The fact that an assembly would also include all the necessary system modules would make it strange to allow nesting. At least it seems that way to me. But... Are we sure we want assemblies to be completely independent artifacts just like fat jars are? It will make it hard to make any kind of composition of assemblies and modules. If they did not include system modules and would still depend on Ceylon being installed on your system they would perhaps be more flexible? And in that case you could probably more easily make an assembly of assemblies. |
Leaving these links here for research purposes: |
No, all I mean is that you would have a fat
Right, exactly. |
P.S. I don't think we have any need for "assemblies" to be composable. By their very nature, assemblies are top level artifacts. |
Ok, thanks, all clear. |
…e to be completely stand-alone while still using JBoss Modules (#6712)
Ok, I pushed my implementation of this to a branch so people can comment on what I created before merging it with master. IntroductionSo the most important part of this design is the realization that if we're talking about putting a bunch of .car (and .jar) files in a single file and calling it an Assembly then basically assemblies are zipped/jarred repositories. From that came the idea that if they are "basically zipped repositories" why not make them actual repositories? Meaning that zipped repositories would be first class citizens of the CMR. So that's the first pillar: Zipped repositoriesSo the Ceylon now support a new special kind of Assembly Repository that lets it look up modules in a zip or jar file. The syntax for the repository URI is the following:
So using the helloworld example code from the
By default Ceylon searches for modules in the root of the zip/jar file, you can change this behaviour by adding the name of a sub folder to search to the end of the assembly path separated by a exclamation mark (
Of course we're not supposed to go around manually creating our own zip files, but it certainly an interesting feature to have and it's the basis for the second pillar: Assemble an assemblyInstead of creating your own zips and perhaps having to figure out which modules to include and which to leave out you can use the new
This creates a NB: Yes, a CAS file. Where JAR stands for Java ARchive, and CAR stands for Ceylon ARchive CAS stands for Ceylon ASsembly, logically This CAS file by default will only contain the module mentioned in the assemble command together with the dependencies explicitly mentioned in its module descriptor and the explicit dependencies of those dependencies etc. So using this new command the above example now becomes:
But of course this isn't much better. But luckily the assemble command isn't just a simple archiver, it doesn't just zip the modules, it also adds some meta-information that the Running assembliesThe
So again using the example above we can now do the following:
Now this is much simpler! The assemble command has stored some important information in the CAS file's MANIFEST.MF telling the run command where to look for the modules and which module is the "main" module that should be executed. NB: in all the above cases the assembly is run using JBoss Modules with full module isolation. The only difference from the norm is that we have a new kind of repository. So these are the basics for creating and using some very light-weight assemblies. They are as small as possible and can easily be distributed and used in places where They could possibly become Ceylon's WAR files where an application server could provide a single Ceylon environment where multiple application assemblies could be installed. But what if you want to use them in places where you do not have Ceylon installed? Well we can do that too. Stand-alone assembliesThere are actually two ways of creating stand-alone assemblies that don't need a local Ceylon installation to run. The first option is very similar to the situation we have when using fat jars:
This creates an assembly that, besides the main module and its explicit dependencies, also includes the Ceylon language module and the minimal set of Ceylon supporting system modules to be able to run with only Java installed on the system. But like fat jars this means running with a flat classpath and with a dynamic meta model. But it works and results in an assembly that's only somewhat bigger (~2MB).
But what if you want a stand-alone assembly but still want to use the full module isolation that JBoss Module provides? Well for that we have a different option:
This creates an assembly that, besides the main module and its explicit dependencies, also includes as much of the Ceylon system modules to be able to run using JBoss Modules. It does result in an assembly that's quite a bit bigger (~7MB).
Advanced topics
CaveatsThere is no support for Maven dependencies. (Things will work when run using Comments?So what do you guys think? @gavinking @FroMage @tombentley @chochos @davidfestal @bjansen @lucaswerkmeister @jvasileff Edit: changed # to ! |
Wow, this looks fantastic @quintesse! I love it, and can't wait to try it out. I have three minor comments:
|
If an assembly is essentially a repo-in-a-file, what about other backends? Could we also use this for JS or Dart programs? |
@lucaswerkmeister Our notion of an "assembly" is now somewhat open ended. We have several assembler tools already, listed here: https://ceylon-lang.org/documentation/1.3/tour/modules/#assembler_tools That is, we already consider fat
We already have a On the other hand, what would be the use of a zipped up archive full of |
@lucaswerkmeister that should definitely be possible, the repository itself is completely backend-neutral (just that right now it's hard-coded to only look at .jar and .car files)
|
Oh @gavinking btw, the whole idea of using In the end the whole thing gets hidden behind the tools that will know how to deal with assemblies directly anyway (like the |
That sounds nice, although an advantage of |
Do all the options that make sense for I mean, to begin with,
Why exactly? Because Aether can't look inside a zip file? Or something else? |
OK, good, fine. |
That touches another thing I wanted to ask. |
@lucaswerkmeister you didn't read what I wrote above entirely, did you? ;) |
Hey, what did you expect when you posted that comment at 3AM and CCed me into it? I diligently read it, and by the time I got to the end, obviously I was so sleepy that I completely forgot that last part :D Next question, then: What’s the difference between |
|
Neither does |
Indeed (well that and the fact that it contains a special class-loader to make it work) |
Really cool. But yeah we should support Maven modules in there. Since it's meant to be entirely self-sufficient with no downloads after the assembly, the only choice we have is packaging a Maven repo in there, and tweak the Aether resolver so that it looks things up in there. If it can deal with non- |
Well or automatically turn them into Ceylon modules, generating a
It's not really non-file. All "several JARs into one JAR" examples I could find really unpack everything into temp space and then delete that again on JVM exit, so that's what this does too. |
The semantics under JBoss Modules would change, especially with
OK so it surely can do that then. |
It uses the same Module Graph as the fat-jar command so I assume it does :)
Would it be possible to use the simpler MavenRepository for this? (The one you wrote a long time ago that simply works with local folders) or do we specifically need the AetherRepository for everything to work correctly? For the rest I imagine that it means adding a |
OK, so it should.
I guess…
No, what I'd do is to have two folders in the zip: ceylon and maven, no? Or you turn them into Ceylon modules during assembly, and respect |
Sure, that's possible, but the |
It would be nice to also have an option to include as little as possible, to minimize the size of standalone assemblies. (Whatever the user doesn't already have cached in Leveraging the download-deps-at-runtime aspect of Ceylon's module system has really helped with the (WIP) VSCode plugin since Microsoft imposes a strict plugin distribution size limit. I am currently requiring that the user install Ceylon separately, but with this, perhaps even that requirement could be removed. |
Sounds great! For JS backend, I guess the format of the |
Well, like I explained you can have assemblies that only contain application code, no Ceylon system modules at all. But that of course means the user does need Ceylon installed. But you could of course combine it with The smallest option (so far) that doesn't need the user to have anything installed (besides Java) is the |
That's not really what I meant. In fact, this wouldn't necessarily even contain application binaries if they were available on Herd. Although I suppose I might be able to just take the output of an Taking this to the extreme, and a bit off topic, would be a Ceylon runner jar that would let you run Ceylon programs without installing Ceylon. Like: java -jar ceylonRunner.jar ceylon.formatter/1.3.1
# same as 'ceylon run ceylon.formatter/1.3.1' The difference between this and a "bare bones" assembly would be that the assembly would 1) know what to run, and 2) possibly embed some dependencies. Edit: and 3) some support for Regardless, great work. |
But isn't this what |
Not totally the same–there are some other "except that"s. |
Do assemblies supersede ceylonb? |
@xkr47 I do not believe it does. ceylonb is development time tool for building, testing and generally interacting with Ceylon compiler toolset while developng Ceylon projects. assemble on the other hand, creates a self-sufficient executable binary artifact... |
@xkr47 They're two different things.
Assemblies are basically just zipped repositories. An easy way to distribute applications. You'd still need Ceylon to use them unless you use of of the stand-alone options to make them usable without having Ceylon installed. The basic (non stand-alone) assemblies could work very well together with |
Merged this with master now. Will continue working on Maven on the branch. |
Excellent! |
Closing this now and opening a new issue for Maven support, |
Currently
ceylon fat-jar
is a great assembly tool that lets you run a Ceylon app usingjavac
. It has one limitation: it implies--flat-classpath
, and doesn't use JBoss Modules for classloader isolation.We need a similar
ceylon assemble
command that similarly produces a fat jar, but with "russian doll" packaging, and which uses JBoss Modules for classloading.This, together with #5955 satisfies the need for "assemblies".
The text was updated successfully, but these errors were encountered: