I have spoken with David Lloyd about this, and he has provided me with some additional information that leads me to believe that this is still a good direction to pursue (certainly while we are doing side-by-side comparison with OSGi)<br>
<br>1. All that is left to make this successful is module dependency management.<br>2. The greatest benefit is that we control the programming model, and don&#39;t require any additional tools above what we already use.<br>
3. We&#39;ve found a way to run Forge from sources within Eclipse (without extra IDE tools.)<br><br>The conversation is below, for others who are interested:<br><br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
lincolnthree<br>hey folks<br>question about JBM and MSC<br>who&#39;s around?<br><br>3:12<br>dmlloyd<br>the usual <br><br>3:14<br>lincolnthree<br>awesome <br>So<br>Question is:<br>What exactly does MSC provide on top of JBM, and can it be used outside of AS7?<br>
<br>3:15<br>dmlloyd<br>nothing, the two are wholly independent<br><br>3:15<br>lincolnthree<br>Okay… so what does MSC provide?<br><br>3:15<br>dmlloyd<br>a concurrent dependency-based service container<br>it starts and stops things<br>
not likely to be useful outside of the app server<br><br>3:16<br>lincolnthree<br>Why not?<br>(Thinking Forge)<br><br>3:16<br>dmlloyd<br>because all an app server is, is services and management<br>if you pull in services to your project, you&#39;re duplicating the app server<br>
<br>3:16<br>lincolnthree<br>Forge is just Plugins (services) and a UI layer of some sort<br>And I&#39;d hope I&#39;m not duplicating the app-server, because I don&#39;t need 99% of what it delivers to users.<br><br>3:17<br>
dmlloyd<br>are you saying you want to use MSC?<br>it&#39;s not really a box to check - you&#39;d only use it if you really need asynchronous concurrent service start/stop<br><br>3:18<br>lincolnthree<br>I&#39;m saying I want to know if it would make any sense, and if it would address any of the problems currently being discussed by Forge<br>
I need to be able to install a plugin, have forge bring up other plugins that may depend on it<br>stop a plugin<br><br>3:18<br>dmlloyd<br>also, AS8 will likely use a largely rewritten version of MSC that is transactional<br>
<br>3:18<br>lincolnthree<br>bring down all dependent plugins<br><br>3:18<br>dmlloyd<br>so 1.x has a limited future lifespan I would expect<br><br>3:18<br>lincolnthree<br>allow plugins to depend on other plugins<br>in a modular environment<br>
(Which I have working right now via a naive proxy system and some dynamic module configuration)<br>Basically I am comparing JBM &amp; MSC to OSGi<br>We are at a crossroads here<br>of giving up JBM in favor of OSGi<br><br>
3:19<br>dmlloyd<br>I wouldn&#39;t recommend that - OSGi is really shit<br><br>3:19<br>lincolnthree<br>And I need to know which path makes most technical sense for my project<br><br>3:20<br>dmlloyd<br>people keep blindly adopting it, and by the time it starts stabbing them in the back they have already convinced themselves that they&#39;re buzzword-compliant<br>
or whatever it is that causes people to use it<br>it&#39;s like struts<br>everyone used it even though it&#39;s complete shit<br>mob psychology I guess <br><br>3:22<br>lincolnthree<br>so maybe you should be involved onthe forge dev list<br>
because the OSGi people are gaining momentum<br><br>3:23<br>dmlloyd<br>maybe, though my time is already limited<br><br>3:23<br>lincolnthree<br>And I&#39;m listening because it sounds like it can address a lot of our problems (in combination with weld OSG<br>
<br>3:24<br>dmlloyd<br>I&#39;m not going to sell these projects to you.  I can only say that OSGi is a mistake that will cost you in the mid- to long-term, and let you make your own choice<br><br>3:24<br>lincolnthree<br>I can&#39;t make an educated choice because there is no documentation about the alternatives.<br>
Which is why I am here with you now.<br><br>3:24<br>dmlloyd<br>I&#39;m not saying the MSC/Modules is a monolithic alternative either<br>the two projects are associated by their usage in AS but they&#39;re by no means connected in any technical manner<br>
<br>3:25<br>lincolnthree<br>You are basically the single point of knowledge for JBM <br>(Aside from a few others at JBoss and myself included I suppose at this point)<br><br>3:25<br>dmlloyd<br>I dunno, the docs spell out the basics pretty well I think<br>
<br>3:25<br>lincolnthree<br>Basics yes.<br><br>3:25<br>dmlloyd<br>modules is only basics <br><br>3:26<br>lincolnthree<br>But you&#39;re telling me &quot;Don&#39;t use OSGi&quot; without explaining an alternative to the service layer <br>
Which is why I&#39;m asking about MSC.<br><br>3:26<br>dmlloyd<br>the alternative is to do something else<br>even a simple start/stop with naive dependency queueing is probably better long-term<br>just because you&#39;ll have control over it, instead of putting your faith in the genie<br>
<br>3:26<br>lincolnthree<br>Hm.<br><br>3:27<br>dmlloyd<br>MSC isn&#39;t a good long-term choice just because 2.x won&#39;t be compatible with 1.x<br>it&#39;s really meant to be the innards of AS and that&#39;s about it<br>
<br>3:27<br>lincolnthree<br>Will MSC2 be any different?<br><br>3:27<br>dmlloyd<br>you could still use it as long as you don&#39;t make the API public though<br>well as always I hope MSC2 will be &quot;the one that sticks&quot;<br>
<br>3:28<br>lincolnthree<br>The API for none of this will ever be public<br><br>3:28<br>dmlloyd<br>I think the odds are better, as we understand the requirements a lot better now that MSC 1 has been in the wild for a while<br>
<br>3:28<br>lincolnthree<br>No matter what we choose, the programming model that plugin developers will see is CDI<br>With some annotations.<br><br>3:29<br>dmlloyd<br>it has (will have) the benefit of being transactional too, so you can &quot;undo&quot; whole multi-step operations<br>
MSC 1&#39;s chief problem is that you can&#39;t really know when it&#39;s &quot;done&quot; with some logical operation<br>which is fine in an environment like AS5/6 where you just put deployments in as you go without any verification step of any sort<br>
and that&#39;s why it is the way it is<br>but it turns out when you have a server control API like AS7 does, people want to know how their operations turned out, and revert them if stuff breaks<br><br>3:30<br>lincolnthree<br>
Hm.<br>Basically here&#39;s the problem I want to solve:<br>Forge has plugins (services)<br>Right now everyone has to re-invent anything because there&#39;s no way of accessing a service from Plugin A in Plugin B<br>So there&#39;s no way to create building blocks, like unix applications<br>
I need Plugin A to be able to use and depend on Plugin B&#39;s exposed APIs<br>And that sounds a lot like what OSGi provides<br><br>3:32<br>dmlloyd<br>well accessing their APIs is not the same as accessing their objects<br>
<br>3:32<br>lincolnthree<br>Explain<br>I&#39;ll clarify<br>Since API&#39;s are objects too <br><br>3:33<br>dmlloyd<br>only conceptually<br>physically, APIs are classes<br>if you want access to an API, modules can create class loading dependencies without any problems<br>
<br>3:33<br>lincolnthree<br>Plugin A has (MathService) - Plugin B uses (MathService from A)<br><br>3:34<br>dmlloyd<br>if you want to manage service lifecycle and manage injections and dependencies in that regard, MSC gives the low-level stuff to do that (we use it as the basis for Java EE injection for example)<br>
<br>3:34<br>lincolnthree<br>Yes.<br><br>3:35<br>dmlloyd<br>if you want real DI based on annotations and descriptors you need something fancier - and even CDI is pretty bumpy when it comes to DI between separate &quot;modules&quot; (not jboss modules, just regular modules in the EE/CDI sense)<br>
in an AS application for example users tend to use EE injection for that<br><br>3:35<br>lincolnthree<br>This si what I am doing right now:<br><a href="https://github.com/forge/core/tree/2.0/plugin-container/src/main/java/org/jboss/forge/container/services">https://github.com/forge/core/tree/2.0/plugin-container/src/main/java/org/jboss/forge/container/services</a><br>
@Service and @Remote annotations control injections<br>And you define your dependencies manually in a config file.<br>Everything from Plugin A is explosed to Plugin B, if plugin B depends on Plugin A<br>This could be more fine grained<br>
but for now that&#39;s how it works<br><br>3:38<br>dmlloyd<br>for class loading dependencies, that&#39;s probably fine<br><br>3:38<br>lincolnthree<br>But only @Services are injectable<br><br>3:38<br>dmlloyd<br>I&#39;ve yet to see a user legitimately need fine-grained filtering in the real world<br>
<br>3:38<br>lincolnthree<br>into another weld container<br>Each plugin has its own weld container<br><br>3:39<br>dmlloyd<br>sounds reasonable so far<br><br>3:39<br>lincolnthree<br>what actually gets injected is a proxy<br>
which is both lazily instantiated when the dependent service becomes avaialble, and also intercepts method calls which set the TCCL to the ClassLoader of the module from which the service was injected (and resets it on completion)<br>
<br>3:40<br>dmlloyd<br>sounds just like EJB <br><br>3:40<br>lincolnthree<br>lol, basically<br>excepte i have no idea how EJBs really work<br><br>3:40<br>dmlloyd<br>you inject proxies<br>they have interceptor stacks which do things like set TCCL<br>
<br>3:41<br>lincolnthree<br>now i feel &quot;special&quot;<br>cool<br>well… in the end, I guess what is really missing from this whole picture is the dependency management and lifecycle stuff<br>bringing up dependencies in the right order, as needed<br>
because right now all the containers come up at the same time<br><br>3:42<br>dmlloyd<br>basically that problem boils down to: a service can start when all its dependencies are satisfied<br>think of it as a counter<br><br>
3:42<br>lincolnthree<br>and the proxies just &quot;start working&quot; as services come up<br><br>3:42<br>dmlloyd<br>the counter stores the number of unsatisfied dependencies<br>when something finishes, it ticks the counters of all its dependents<br>
when those counters hit 0, that dependent can start<br><br>3:43<br>lincolnthree<br>right. makes sense<br><br>3:43<br>dmlloyd<br>that&#39;s basically all there is to it<br>MSC takes this idea and goes nuts with it<br><br>3:43<br>
lincolnthree<br>i kind of wonder how much more what I have actually needs<br><br>3:43<br>dmlloyd<br>makes everything concurrent, with injection, lots of modes like ON_DEMAND and so on, complex error handling<br><br>3:43<br>
lincolnthree<br>ON_DEMAND would be nice<br><br>3:44<br>dmlloyd<br>MSC 2 will be simpler but also more complex<br><br>3:44<br>lincolnthree<br>I guess I could do that too<br><br>3:44<br>dmlloyd<br>simpler in that there are fewer states for a service, but more complex in that it&#39;s transactional<br>
<br>3:44<br>lincolnthree<br>not sure i really need transactional<br><br>3:44<br>dmlloyd<br>so you&#39;d open a txn, add all your services (which in turn might add more services or do other things like stopping services), then prepare and if there are no errors, commit<br>
<br>3:45<br>lincolnthree<br>hm<br><br>3:45<br>dmlloyd<br>if there are errors, report and roll back<br>3:45<br>jamezp<br>Couldn&#39;t you use to rollback a failure to load a plugin lincolnthree?<br><br>3:45<br>dmlloyd<br>well, let&#39;s not go selling vaporware just yet <br>
<br>3:45<br>lincolnthree<br>jamezp: well… what happens is the plugin just doesn&#39;t load<br><br>3:45<br>dmlloyd<br>I still don&#39;t actually have a working prototype<br><br>3:45<br>lincolnthree<br>nothing else blows up<br>
unless it depends on that plugin<br><br>3:46<br>dmlloyd<br>but, I need one within about two weeks, so... <br><br>3:46<br>jamezp<br>has faith in dmlloyd <br><br>3:46<br>lincolnthree<br>but if it does, then i assume if I get this all wrking, the dependency would also not come up <br>
<br>3:48<br>dmlloyd<br>yeah dependents as a rule will just sit there until their dependencies appear<br>in AS5/6, you&#39;d just remove broken stuff and put in the right stuff and it would (hopefully) all fix itself<br>that&#39;s the MSC 1 &quot;way&quot;<br>
in MSC 1, things actually *do* fix themselves once you correct dependency issues<br>also you can &quot;poke&quot; failed services to make them try again<br>like if there&#39;s a port binding conflict, something you can fix manually<br>
<br>3:50<br>lincolnthree<br>interesting<br>one downside of JBM is that I can&#39;t run it from an eclipse launch very easily<br>because the module path needs to be configured<br>module library, etc<br>which is of course, sensible<br>
<br>3:51<br>dmlloyd<br>well, yes and no<br><br>3:51<br>jamezp<br>Sounds like you need a plugin for that <br><br>3:51<br>dmlloyd<br>you could for example have a flat-classpath application which uses jboss modules<br>one of the things I&#39;m doing for modules 1.2 is making it more friendly for this kind of thing (a lot of bootstrappy stuff happens in main() and it should be factored out)<br>
but iirc it&#39;s possible to do<br>iow you use modules for your loaded plugins and a flat classpath for the static stuff<br>mainly I&#39;m working on that to make testing easier, but it probably applies here too<br><br>3:53<br>
lincolnthree<br>that would be really nice<br>any idea when that might happen?<br>that would make forge development a LOT easier<br><br>3:53<br>dmlloyd<br>it should already be possible just by using it<br>you might have to hack around a quirk or two though<br>
won&#39;t know for sure until it happens <br><br>3:55<br>lincolnthree<br>hm.<br>Interesting… So then I would need to<br>supply a module library as an argument to JBM when I started it from my class<br>and basically just call JBM main from some other class?<br>
But then JBM would also need a main method to invoke ?<br>How would I get a handle to the BootLoader<br>Lots of questions<br>I don&#39;t have a clear picture of that in my mind<br>Well. I&#39;ll come back to that later<br>
thanks for your thoughts dmlloyd<br><br>4:05<br>dmlloyd<br>JBM doesn&#39;t need a main method<br>think of it as a class loader factory<br><br>4:05<br>lincolnthree<br>Ahhhh …. interesting<br><br>4:05<br>dmlloyd<br>you just call reflectively in to whatever module when it&#39;s ready<br>
like ServiceLoader does, or whatever<br><br>4:05<br>lincolnthree<br>I think the last time I looked at it … you couldn&#39;t do that<br>What&#39;s the starting API for which I need to use that kind of functionality?<br>the entry point to start exploring<br>
<br>4:06<br>dmlloyd<br>just create a ModuleLoader<br>that&#39;s really the starting point of the API<br><br>4:06<br>lincolnthree<br>Huh.<br>But in this case I would have no SystemModuleLoader, right?<br><br>4:06<br>dmlloyd<br>
it&#39;s just that by default jboss-modules.jar creates one for you<br>well, all module loaders can have a system dependency<br>SystemModuleLoader isn&#39;t really a &quot;thing&quot;<br>you wno&#39;t have that initial filesystem-backed one though, no<br>
<br>4:17<br>lincolnthree<br>Huh… go figure.<br>ModuleLoader addonLoader = new AddonModuleLoader();<br>That&#39;s all it takes.<br>So Forge itself has a flat classpath when it is loaded<br>but the modules themselves do not<br>
the addons<br>interesting<br>I guess that&#39;s the concept?<br>For some reason I had it in my head that you would need to be running in a modular environment for ModuleLoader to work<br>that makes things about 500x easier<br>
if it is true<br><br>4:24<br>dmlloyd<br>I&#39;d certainly love for everyone to run in a modular environment, but I recognize that it isn&#39;t always possible <br>but yeah that&#39;s the gist of it<br><br>4:25<br>lincolnthree<br>
nice<br>im trying this right now<br>a few more hacks to make<br>but i think this could be the lynch-pin to OSGi <br>4:25<br>alesj left the room (quit: Quit: Leaving.).<br>4:27<br>alesj [~alesj@redhat/jboss/alesj] entered the room.<br>
4:27<br>mode (+v alesj) by ChanServ<br><br>4:27<br>lincolnthree<br>also would simplify the build greatly<br>removing the need for modules assembly<br>well i&#39;ll be...<br>looks like it should work<br>gonna have to ruminate on this<br>
thanks dmlloyd<br>question though<br><br>4:31<br>dmlloyd<br>np<br>go ahead<br><br>4:31<br>lincolnthree<br>will loaded modules also have exposure to what is on the classpath? I assume yes?<br><br>4:32<br>dmlloyd<br>yes, with the qualification that you&#39;ll have to add a dependency for that purpose<br>
<br>4:32<br>lincolnthree<br>or are subsequent loaded modules still truly isolated?<br><br>4:32<br>dmlloyd<br>since that dependency needs a comprehensive package list, you&#39;ll have to iterate the class path to assemble that information<br>
<br>4:32<br>lincolnthree<br>okay, so they are still isolated unless you add… what, the system dependencies module?<br><br>4:33<br>dmlloyd<br>they&#39;re isolated unless you add a system dependency - it&#39;s a dep type, not a module<br>
<br>4:33<br>lincolnthree<br>right<br><br>4:33<br>dmlloyd<br>even then you have to list the packages you want to be visible<br>so if isolation by default is your goal, that&#39;s probably a good thing<br>if you want the whole classpath exposed then like I said you have to resort to a dirty trick to do it<br>
<br>4:34<br>lincolnthree<br>I don&#39;t<br>I just want what is currently done by JBM when including the system module<br><br>4:34<br>dmlloyd<br>though there&#39;s a different sort of dirty trick that you can do which we don&#39;t use much: &quot;fallback&quot; dependencies<br>
<br>4:34<br>lincolnthree<br>which i imagine means replacing the module.xml with some programatic stuff<br><br>4:34<br>dmlloyd<br>are you using 1.0.x?<br>system module has been gone since 1.1.0<br>replaced with system dep type<br>
<br>4:35<br>lincolnthree<br>checking..<br><a href="http://1.1.3.GA">1.1.3.GA</a><br><br>4:36<br>dmlloyd<br>okay then a system dependency is identical between XML and programmatic API<br>basically you list the packages you wanty<br>
<br>4:36<br>lincolnthree<br>javax.api module.xml:<br><br>                &lt;path name=&quot;javax/accessibility&quot; /&gt;<br>                &lt;path name=&quot;javax/activity&quot; /&gt;<br>                &lt;path name=&quot;javax/crypto&quot; /&gt;<br>
                &lt;path name=&quot;javax/crypto/interfaces&quot; /&gt;<br>so just build that<br><br>4:36<br>dmlloyd<br>(&quot;java.&quot; is always available though, as is &quot;sun.reflect.&quot;)<br>right<br><br>4:36<br>
lincolnthree<br>got it<br>it&#39;s only 115 paths <br>no problem<br>nothing a little VI can&#39;t solve<br><br></blockquote><br><br><br clear="all"><br>-- <br>Lincoln Baxter, III<br><a href="http://ocpsoft.org" target="_blank">http://ocpsoft.org</a><br>
&quot;Simpler is better.&quot;<br>