why multiple class loader for each instance of Verticle

1,105 views
Skip to first unread message

Alex Tkachman

unread,
Jul 19, 2012, 2:00:40 AM7/19/12
to ve...@googlegroups.com
Hi!

I am curious why vertx choose to create separate class loaders for each instance of the Verticle. If we create HttpServer with 10 instances we probably don't need or want 10 identical class loaders. Looks like too high price for illusion of isolation between instances.

--
Best regards,
Alex

Best way to call / chat with me
http://lucy.me/alex

Tim Fox

unread,
Jul 19, 2012, 2:59:40 AM7/19/12
to ve...@googlegroups.com
This is so verticles can't share mutable state by, say, using static members of classes.

One of the features of Vert.x is to protect users from having to worry about concurrent access as this is one of the most common sources of errors in Java programs.

If they could, then that state would need to be protected against concurrent access (synchronized, volatile, locks etc), and we wouldn't be able to make the claims we make on the website or docs about concurrency.

Alex Tkachman

unread,
Jul 19, 2012, 5:00:02 AM7/19/12
to ve...@googlegroups.com
OK, let me ask practical question, which illustrates general problem.

I have Freemarker template cache - efficient and lovely synchronized tool. Today to share it (subclass which is Shareable) between verticles of the same HttpServer I have to put freemarker classes in to system class path - otherwise each verticle of the same server has it is own class.

I totally agree with approach when verticles of different deployments have different class loaders but when I start N instances of the same verticle I believe we should either trust to developer or at least provide easy way to share data.

Ehcache or gridgain or any other caching solution will have the same problem.

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To view this discussion on the web, visit https://groups.google.com/d/msg/vertx/-/woENCt4P04sJ.
To post to this group, send an email to ve...@googlegroups.com.
To unsubscribe from this group, send email to vertx+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/vertx?hl=en-GB.

Tim Fox

unread,
Jul 19, 2012, 4:03:40 PM7/19/12
to ve...@googlegroups.com
This is a tricky one. If we allow different verticle instances, even of the same type to see the same classes, then people _will_ abuse it, trust me ;)

Let me ponder this one a while. Hopefully there is some solution which allows you to do what you want without breaking the isolation.
To unsubscribe from this group, send email to vertx+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/vertx?hl=en-GB.

Tim Fox

unread,
Jul 19, 2012, 4:18:13 PM7/19/12
to ve...@googlegroups.com
I guess we could make the isolation optional for any particular verticle or module. Still not 100% sure this is a good idea though.

Wilson MacGyver

unread,
Jul 19, 2012, 4:23:14 PM7/19/12
to ve...@googlegroups.com
I feel icky :)
>>>> vertx+un...@googlegroups.com.
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/vertx?hl=en-GB.
>>>
>>>
>>>
>>>
>>> --
>>> Best regards,
>>> Alex
>>>
>>> Best way to call / chat with me
>>> http://lucy.me/alex
>>>
> --
> You received this message because you are subscribed to the Google Groups
> "vert.x" group.
> To view this discussion on the web, visit
> https://groups.google.com/d/msg/vertx/-/4qRfjKoim0kJ.
>
> To post to this group, send an email to ve...@googlegroups.com.
> To unsubscribe from this group, send email to
> vertx+un...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/vertx?hl=en-GB.



--
Omnem crede diem tibi diluxisse supremum.

Tim Fox

unread,
Jul 19, 2012, 4:26:13 PM7/19/12
to ve...@googlegroups.com
On 19/07/2012 21:23, Wilson MacGyver wrote:
> I feel icky :)

Icky good or icky bad? ;)

Alex Tkachman

unread,
Jul 19, 2012, 4:49:48 PM7/19/12
to ve...@googlegroups.com
Tim, 

we provide the simplest way to abuse already now - just put your classes in to system class loader. I think we should not prevent people from doing things concurrency where natural and more efficient - from my prospective it is enough to stimulate developers to do things right but leave enough room for experts and system developers to create tools/plugins for others.

Alex

To view this discussion on the web, visit https://groups.google.com/d/msg/vertx/-/cwJEoqdLkmoJ.

To post to this group, send an email to ve...@googlegroups.com.
To unsubscribe from this group, send email to vertx+un...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/vertx?hl=en-GB.

Wilson MacGyver

unread,
Jul 19, 2012, 7:13:50 PM7/19/12
to ve...@googlegroups.com
Icky bad, it's probably my erlang bias. :)

Tim Fox

unread,
Jul 20, 2012, 3:42:14 AM7/20/12
to ve...@googlegroups.com
I tend to agree.

Although Vert.x isn't a pure actor implementation it does clearly take inspiration from the Actor Model, in that each Verticle is strictly single threaded and serialises all processing and most concurrency is done by message passing between Verticles. This is an attempt to get away from the "bad old world" of Java style shared state concurrency which is the source of so many problems.

On the other hand, Vert.x is not a pure implementation like Erlang, and we can't expect all traditional Java libraries to be rewritten overnight. So we have to have a story for effective using those libraries from within Vert.x. So, it's a balancing act.

Vert.x already contains a mechanism for dealing 'traditional' Java blocking libraries - and that's to use them from within 'Worker Verticles'. A worker verticle is executed on a pooled thread, not an event loop so it can block for significant time without effective the responsivity (is that a word?) of the application.

Perhaps we can use worker verticles also for talking to libraries, like Alex's templating library which rely on caching? If we drop isolation (optionally) in Worker verticles (but not in normal verticles), then the cache should work as expected. The worker verticle could then be talked to from other verticles by sending messages on the event bus, without breaking the concurrency model. We could even wrap the worker verticle in a module so it can be reused by others.

>>>>>> For more options, visit this group at
>>>>>> http://groups.google.com/group/vertx?hl=en-GB.
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Best regards,
>>>>> Alex
>>>>>
>>>>> Best way to call / chat with me
>>>>> http://lucy.me/alex
>>>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "vert.x" group.
>>> To view this discussion on the web, visit
>>> https://groups.google.com/d/msg/vertx/-/4qRfjKoim0kJ.
>>>
>>> To post to this group, send an email to ve...@googlegroups.com.
>>> To unsubscribe from this group, send email to
>>> For more options, visit this group at
>>> http://groups.google.com/group/vertx?hl=en-GB.
>>
>>
>
>
> --
> You received this message because you are subscribed to the Google Groups "vert.x" group.
> To post to this group, send an email to ve...@googlegroups.com.
> To unsubscribe from this group, send email to vertx+unsubscribe@googlegroups.com.

Tim Fox

unread,
Jul 20, 2012, 3:43:53 AM7/20/12
to ve...@googlegroups.com


On Thursday, July 19, 2012 9:49:48 PM UTC+1, Alex Tkachman wrote:
Tim, 

we provide the simplest way to abuse already now - just put your classes in to system class loader.

Ok, so you found a way around it :) But this hole is very easy for me to plug.

Fundamentally with any open source application you can find ways around the "rules" (e.g. you can change the code and recompile it if you want) ;)

Tim Fox

unread,
Jul 20, 2012, 4:08:19 AM7/20/12
to ve...@googlegroups.com
One thing I'm curious about - aiui, most app servers, servlet engines etc also provide isolation and deployments normally have their own classloader.

Does freemarker also work with those? If so, how?
To unsubscribe from this group, send email to vertx+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/vertx?hl=en-GB.

Alex Tkachman

unread,
Jul 20, 2012, 4:32:19 AM7/20/12
to ve...@googlegroups.com

Sure it does.
The difference is that in vertx each thread is isolated while in traditional server unit of isolation is whole app.

--------
Best regards,
Alex

Best way to call / chat with me http://lucy.me/alex

To view this discussion on the web, visit https://groups.google.com/d/msg/vertx/-/yIu66CBP15cJ.

To post to this group, send an email to ve...@googlegroups.com.
To unsubscribe from this group, send email to vertx+un...@googlegroups.com.

Bruno Bonacci

unread,
Jul 20, 2012, 4:55:56 AM7/20/12
to ve...@googlegroups.com
.... If we drop isolation (optionally) in Worker verticles (but not in normal verticles), then the cache should work as expected. The worker verticle could then be talked to from other verticles by sending messages on the event bus, without breaking the concurrency model. We could even wrap the worker verticle in a module so it can be reused by others.

 
I like this, sounds like a good compromise between the good design choice and solving practical problems. This could also solve few other problems in the embedded mode discussed a couple of weeks ago.

+1 

Marco Ellwanger

unread,
Jun 8, 2015, 1:28:06 AM6/8/15
to ve...@googlegroups.com
I am working on annotation-based routing where Verticles can auto-mount a sub-router to the main router for eligible methods (following the service-proxy style), where the plumbing and RoutingContext handling is auto-generated. When I hit the isolation issue I initially thought the problem is limited to my Holder class (marked Shareable) for the "global" main router. So you can either exempt it by adding it to the vertx "system" classes or use reflection to just access the contained object. On first glance it seemed that isVertxOrSystemClass would include most if not all vertx modules supplied on the initial classpath, however it only includes io.vertx.core. That enables you to "share" instances of any classes in core, such as HttpServer, but not Router in ext.web. Just for kicks I included anything vertx-web in isVertxOrSystemClass (using runtime javaagent instrumentation via javassist, no recompilation necessary) and it seems to work fine now. I currently don't see another way to achieve this, any alternative comes with enormous code and message bloat. Please don't plug any holes, I think we should allow flexibility at our own risks ;) But any further ideas on this or future plans are welcome.

Tim Fox

unread,
Jun 8, 2015, 3:17:56 AM6/8/15
to ve...@googlegroups.com
I'm a bit confused -you're replying to a message from 2012 that was
referring to the old Vert.x 2 classloader model, but you seem to be
referring to Vert.x 3 which has a completely different classloader model.

Could you clarify?

On 08/06/15 06:28, Marco Ellwanger wrote:
>
> On Friday, July 20, 2012 at 1:55:56 AM UTC-7, Bruno Bonacci wrote:
>> .... *If we drop isolation (optionally) in Worker verticles (but not in
>>> normal verticles),* then the cache should work as expected. The worker

Marco Ellwanger

unread,
Jun 8, 2015, 10:59:55 AM6/8/15
to ve...@googlegroups.com
Sure. in vertx-x3 each verticle is loaded by its own instance of the IsolatingClassloader. Say the first verticle gets deployed by the starter and it auto-installs a restful API (via code located in a base class) which lets you deploy more verticles via Http. Since it is also the first verticle in the Vert.x instance, it initializes a reference to a main Router and puts it into the instance-wide shared-data. Now another Verticle gets deployed by this verticle via a restful API call, this verticle starts up in its own IsolatingClassloader as well and also has restful annotations. When this Verticle wants to mount its sub-router to the main router it obtains the reference to the main Router from the shared data. However since any package from io.vertx.ext.web will be loaded by its own classloader, it cannot share any instances of these classes, e.g. retrieving the main Router would cause a ClassCastException. From this thread https://groups.google.com/forum/#!topic/vertx/sFVLFnxFzPc it looks like the only way to share a router hierarchy is if the main router is an instance or shared variable (as opposed to the HttpServer which vertx cleverly auto-detects to already be listening on the same port and hence shares). Hope this clarifies it a bit. I am wondering if it would make sense to allow some control about what are considered vertx core classes or if there is another way to share more than the io.vertx.core (and Java runtime) classes across a vert.x instance.
cheers

Tim Fox

unread,
Jun 8, 2015, 11:05:36 AM6/8/15
to ve...@googlegroups.com
On 08/06/15 15:59, Marco Ellwanger wrote:
> Sure. in vertx-x3 each verticle is loaded by its own instance of the
> IsolatingClassloader.

This is not the case normally. By default V3 has a flat classloader
model - i.e. we don't create classloaders during verticle deployment.

V3 does support IsolatingClassloader if you specifically opt to use it
(it's not the default), but it's not expected this is used by 99% of
users, only those that specifically want classloader isolation.

Can you elaborate on how you are deploying your verticles?

Marco Ellwanger

unread,
Jun 8, 2015, 11:16:46 AM6/8/15
to ve...@googlegroups.com
The initial verticle is launched on the command line via io.vertx.core.Starter run maven:com.foo... when vertx is started via /etc/init.d. This initial verticle has a restful endpoint which allows you to upload and deploy more verticles from a local maven repo. It deploys those verticles via vertx.deployVerticle(<coords>, options, handler). Any verticles deployed by the "deployer" verticle have their own IsolatingClassloader which has the deployer verticle's classloader set as its parent and so they don't seems to share classes other than those listed in IsolatingClassLoader.isVertxOrSystemClass.

Marco Ellwanger

unread,
Jun 8, 2015, 11:24:30 AM6/8/15
to ve...@googlegroups.com
Also we're not using any special deployment options or isolation settings and are using milestone6.

Tim Fox

unread,
Jun 8, 2015, 11:32:04 AM6/8/15
to ve...@googlegroups.com
Ah, you're using the maven verticle factory, rather than deploying
verticles directly.

Yes, that does use IsolatingClassloader, it has to be that way as we
need to construct a classpath dynamically for the verticle that you are
deploying, and that's not possible without classloaders.

Marco Ellwanger

unread,
Jun 8, 2015, 11:46:28 AM6/8/15
to ve...@googlegroups.com
Got it. Would it make sense to provide an option to use the traditional model and have the (in this case not-so) isolating loader ask its parent first so verticles in a deployment hierarchy would share all classes already loaded but keep any new classes horizontally isolated? The 100% dynamic but controlled deployment (in addition to the polyglot nature) is really one of the killer features for us and hence we already brought back verticle dependency awareness (which used to be module-dependency in vertx 2) via a json config setting in the descriptor for vertx-3.
Thanks

Tim Fox

unread,
Jun 8, 2015, 12:38:32 PM6/8/15
to ve...@googlegroups.com
On 08/06/15 16:46, Marco Ellwanger wrote:
> Got it. Would it make sense to provide an option to use the traditional
> model and have the (in this case not-so) isolating loader ask its parent
> first so verticles in a deployment hierarchy would share all classes
> already loaded but keep any new classes horizontally isolated?

Perhaps this could be an option, but it wouldn't work well in general.
The idea with the Maven verticle factory is you can deploy different
verticles from Maven and the entire dependency graph for the artifact
you're deploying is isolated - this is important - e.g. Artifact A might
use a different version of the same library as Artifact B with the same
classnames, if we use a parent first model they will clash.

Usually I wouldn't recommend an architecture where you share classes
(e.g. Routers) between verticles, it's quite un-Vertxy. If you add
routes to a router from a different verticle from another verticle than
that route is going to run in the context of the router verticle not the
one that added it, so you're kind of breaking the Vert.x advantages and
simplicity that the Vert.x threading model guarantees.

Also, how are you going to scale the system? Unless you want your server
running on a single thread I assume you have multiple instances so you'd
have to add your subrouter to all the instances, not just 1...

Tim Fox

unread,
Jun 8, 2015, 12:55:43 PM6/8/15
to ve...@googlegroups.com
On 08/06/15 17:38, Tim Fox wrote:
> On 08/06/15 16:46, Marco Ellwanger wrote:
>> Got it. Would it make sense to provide an option to use the traditional
>> model and have the (in this case not-so) isolating loader ask its parent
>> first so verticles in a deployment hierarchy would share all classes
>> already loaded but keep any new classes horizontally isolated?
>
> Perhaps this could be an option, but it wouldn't work well in general.
> The idea with the Maven verticle factory is you can deploy different
> verticles from Maven and the entire dependency graph for the artifact
> you're deploying is isolated - this is important - e.g. Artifact A
> might use a different version of the same library as Artifact B with
> the same classnames, if we use a parent first model they will clash.

So we could do this as an option, it wouldn't be hard, we'd just use a
standard URLClassloader instead of an IsolatingClassloader, but it would
be up to you to make sure none of your artifacts use different versions
of the same classes as there would be no isolation.

>
> Usually I wouldn't recommend an architecture where you share classes
> (e.g. Routers) between verticles, it's quite un-Vertxy. If you add
> routes to a router from a different verticle from another verticle
> than that route is going to run in the context of the router verticle
> not the one that added it, so you're kind of breaking the Vert.x
> advantages and simplicity that the Vert.x threading model guarantees.
>
> Also, how are you going to scale the system? Unless you want your
> server running on a single thread I assume you have multiple instances
> so you'd have to add your subrouter to all the instances, not just 1...

I guess you would have to add a structure that contains the list of all
your routers to the shared data, and your sub verticles would add routes
to all instances.

Marco Ellwanger

unread,
Jun 8, 2015, 2:03:06 PM6/8/15
to ve...@googlegroups.com
Thanks, that sounds feasible. It would also alleviate memory concerns (due to class bloat for the same classes) in a system were verticles are mainly deployed via (maven) service factories, no matter whether one actually ends up using shared instances. It could be a simple deployment option and yes, the burden would be on the caller to ensure there are no issues due to ditching isolation. 

Sean Fitts

unread,
Jun 8, 2015, 2:17:54 PM6/8/15
to ve...@googlegroups.com

Tim, hi.

I'm curious if there is a "vertxy" solution to this problem.  In general it seems useful to permit a model where newly loaded verticle can add their own routes.  Is there a way to do this without having multiple HTTP listeners?  Can there be multiple routers on the some HTTP server each of which handles their portion of the route tree?

Sean
Reply all
Reply to author
Forward
0 new messages