 Welcome back to the next technical session in this conference by the name of runtime specialization. Java has never been so dynamic before, and I should admit there's a lie in the title. This will not be about the next version of Java, but what I will be talking about is a language that builds on top of Java and enhances Java by some fundamentally new concept on the languages called object teams. Though I am a committer on JDT course, so I work a lot with Java. This project is a separate project, the object teams project. My name is Stefan Halman, and in my day job I work with this company, GK Software, which nobody has heard of. I don't blame you. We're doing retail software in Germany and some other places over the world. But this is about object teams, and the story I want to tell you will start with telling you that the word is separated into two camps, I mean the software word in particular. So I live in what you might call a city. And in the city, people are speaking static languages. And by that I mean that we have, the languages that we speak are static type systems, which comes with strict rules. And we like this because then if we say something wrong, there is a tool called compiler that will immediately tell us that we made a mistake. And so we can correct our mistake. So the staticness is there to help us. And we also like this staticness of our static languages to help us to build systems from modules. So there's boundaries around individual parts and the real software is encapsulated in these boundaries like brick walls around the places where people live. And we like this because it helps us to separately maintain our individual building blocks of our software. And in order to have this benefit, we need to enforce these boundaries, not by arms in this case, but we want to enforce the boundaries because then for example, if something goes wrong somewhere in our software, we know exactly which place, which part of the software is to blame or even better in addition to blame assignment, maybe we can even use this strict encapsulation to prevent a whole lot of mistakes that we might be doing. So all is great in this part of the world, cities with boundaries, building blocks, walls, everything. I've been told there's another part of the world where people live in completely different settings. So they don't have a city. They have a far-sight camp. And in this part of the world, people speak what they call dynamic languages. And why do they do that? They don't like ceremony, that they don't like to say public static void, et cetera. They only want to say the real things that have meaning to them. And they like to enjoy the freedom that anything they can say, they want to say, they really can say. And they can put the bits and pieces of their programs anywhere they want. And there's no boundaries that stop them from doing anything they want. And the flexibility amounts even to a drastically things like that. The program, the writing could, for example, modify itself even more. The program they're writing could modify the language that they're writing it in. And I must admit, I have been a visitor to this country and enjoyed the freedom to have a program that on the fly modified the language that was written in from a purely procedural language to an object-oriented language, just by means of some snippets of code that I had to put into the interpreter. Well, that was fantastic. That was amazing, this freedom. We can do everything. But I admit, whenever I want to do some software that I want to ship to anybody outside my own private circle, I feel much safer going back to the city or we have the rules or we know in advance whether we made some big mistakes or not. We have some restrictions, but we are safe in this place. Using these bearings blocks, I mean, there's boundaries and what we get from these boundaries. There's lots of building blocks on the shelves and around the world that I can pick and integrate into my own application. I'm free to choose any of them. I'm free to compose them, but I do not get permission to open any of these boxes and change anything inside. So that's a contract. I have the freedom only to compose what's there, no changes to be made. Once you open the screw, warranty is broken and broken to seal. Unfortunately, when we do this story with the building blocks, every now and then, I come to a situation what I call a near miss. So there's lots of blocks and then the last piece that's missing in my application is this red block. Well, I have a round hole. So I could use a hammer to get the red square peg into the round hole. It looks like a good match at the first sight, but we're doing investigation at some point and I find it doesn't total with it. It's only a near miss. So what do I mean by that? And let me start by enumerating the choices we have if we encounter near miss. So regularly, if you're using a component that doesn't exactly do what you expect it to do, you could just say, well, I would just do what that component does and maybe I'll drop some details and the requirements for my customer. Because the component doesn't fulfill these requirements, let's just drop those requirements or adjust them, let's put it that way. The problem is, customer will not be delighted. They will probably move away. So this is not a very competitive way of building software to adjust the functionality to the building blocks that you already have. So what's the other alternative? Well, I could just drop that block and instead of using the thing that almost fits, discard it and create the entire thing just from scratch. Totally new. Just write your own component that's perfect match for what you want to do. That works, but you will be very slow and the product will be very expensive because you will be building a lot of software from scratch that exists already there almost exactly like you wanted. So that's not a good problem to have, right? So let's step, why are we having this problem in the first place? Well, as a matter of fact, we see it's just a technical impossibility to reuse something and make it do something that it was not made for, right? So it's just not possible. A square peg is a square peg. It doesn't fit in the round hole. We still have the problem and I decided that's a good problem to have. Wait a minute, we're talking about software. Is the answer technical impossibility a good answer for anything in software? Rarely, so let's discard that answer. That doesn't qualify as an answer. So looking more closely at the problem, well, it's not technical impossible. It's just because we chose those roots that we want to live with these boundaries and we saw some benefits in the boundaries. So we decided, yes, we want that, we want the static checking, we want the enforcement of everything. So we chose that. Well, okay, that's when I started to become envious of those who live on the fireside camp and they don't even have my problem. So what they can do is what you could call unlimited adaptation or maybe more to the point you could say they can do any adaptation be it anticipated or not anticipated. So somebody built that red block. They didn't anticipate that it should fit into a round hole. So if I adapted to fit into that hole, this is some unanticipated adaptation. So moving away from cities and fireside camps what do I mean by unanticipated adaptation in terms of a real simple example with software? Assume that you are picking from some shelf a component that implements a stopwatch. Tiny is most example that could explain the story. A component that has facilities you can start a stopwatch, you can stop it, you can clear it and internally it has a method tick and let's say for every second it makes a tick and advances the clock. Great, so that's what you get from the shelf. Your job now is to display this stopwatch on the screen. So you write a watch display. No problem, I can use that to display this. So all the buttons I have in my display, a clear start and stop button are directly mapped by just calling methods of the component that I got. And then I have this task. I need to connect the tick method to the update method. So whenever the clock advances I want my display to update. So how do I connect these two methods? I answer as I don't because for this direction I don't have any technical means. So of course everybody doing object-on-to-program the design pattern that would solve this. So we need a listener infrastructure but the near miss here is the stopwatch. Simple doesn't have the listener infrastructure. It doesn't have a method register update listener or register listener. It doesn't have a method remove listener. It doesn't have the structure of listeners that should be involved. So we would know a solution but the solution is not there and we have no chance to after the fact insert the listener into the stopwatch. That's something that's inside the box. We're not allowed to open that. At this place, it looks pretty much like it did end. We need to do something which we're not allowed to do. So I could weigh the alternatives and one of the alternatives would be, well maybe I should grow potatoes instead of writing Southburg. Maybe instead of Eclipse I should use two tools like that. I'm not good at growing potatoes and I'm a software engineer. I'm not content with that kind of answer. I want this to be solved. So what I want is the mechanism, I think what called method call interception. I wanna be able to intercept every call to the tick method and redirect or make it a trigger to invoke the update method. And of course there is solutions to that that use infrastructure. So if you create a component in some component container you could wrap it into some interceptors, et cetera, et cetera. That's a pretty heavy weight solution. What I want is to have this concept of method call interception at the core of my language. So this should be a fundamental concept of my programming. So I want a language solution for this. How could I do this? Basically I'm just adding one more compartment to this class in this diagram and in this compartment I simply say update after tick. Which simply means that the watch display instructs the stopwatch that it wants to be invoked. So I'm installing a hook into the black box thing into the tick method and that hook should invoke my update method. Well, and in fact as a language designer I can do exactly that and that's what we do in object teams. We have a language construct that creates a method binding and because we have two directions you will see in the future, we call this a call in method binding because we are instructing the stopwatch thing to call in to the update method. Comes in three flavors. Sorry, strawberry is out but we have before after and replace which means that I can install the trigger so that it triggers at the entry of the method or at the end or that actually the new method replaces the original one. At this time, demo time. Let's see how it looks like in the IDE. I have a couple of examples here and I start with the simplest one. The stopwatch is what we saw and what you see here is a special class that has exactly the syntax we saw. Well, maybe let's start by running it. Let's start by running it. And I'll explain later. Here it is. So we hook directly into run as Java application and the real surprising rocket science technology you see here is a real model of view controller application even of two displays displaying the same watch so if I push stop on the digital one also the analog one will stop if I push start here, both of them will start advancing. Cool, right? Well, everybody has seen some model view controller applications. So what's special about this? We have a watch display that is bound to the stopwatch example and the connection is actually made down here in a line like this. Exactly the syntax as I showed it on the screen just listing a method that you want to be invoked then I have this right to left arrow that designates a direction and then say this should happen after any call to the method advance where advance is the method of the stopwatch. Maybe it's more believable what's happening here if we actually look at it in the debugger I already placed the break point in this method advance so this is the black block box thing assumed to be and then debug this, nothing happens so far but as soon as I start the stopwatch debugger kicks in, we're at the break point and now some dispatch code is happening here which shouldn't be interesting to the user so I just grayed it out in the debug view and after the method has executed the debugger indeed takes me just to this interception declaration which is the call in binding after if I step into that, well first I have to look at the watch display instance that is used here and then I can step into this update method. You actually see that the debugger knows that this is a very special stack frame that's not part of any method body but this is a stack frame that corresponds to this declarative method binding so we highlight it in green so you know that's special code. Then we go into this method and there's a method called getValue. Well the display doesn't really have a getValue method the getValue method is something that corresponds to the stopwatch to the model of this model view controller setting so this is where we have a second kind of method binding now we're going from the disk UI to the model so the arrow is from left to right here and you can see I'm directly navigating to the original backbox thing fetch a value from here and use that value to display it in my current UI. So for the time being that's all I wanted to show with this example. Breakpoint will kick in a continuous every second so here's one of the clocks, here's the other one. So they are still running and the reason how I could connect the way how I could connect the UI to the model is exactly with this one line that declares the afterbinding between those methods. Stop this, go back to slides. So if there's different interceptions to the same method yes there's precedence rules there is but in order to explain these precedence rules I would need some more concepts that I haven't mentioned yet but the main message is yes it's completely under your control to say there is some ways where you can complete one interception can completely suppress the other interception or there's situations where we just have an order where first this one and then that one is called but the main notion is nothing is left at random. So time to explain a little bit of the terminology that I have partly already been using in the example and so I was trying to avoid some of the words but what's really the concept behind this? So method called interception is a basic mechanic we have but there's a more fundamental concept behind and this is already alluded to by this stereotype played by which doesn't make sense on its own it only makes sense if you include two more notions because we consider the UI class in this example as a role of the base class stopwatch and so for that I should probably take a few minutes to explain what I mean by role because this is such a fundamental concept in software engineering in total and in particular for programming it's I believe one of the most powerful concepts we could add to languages like Java so we did. Let me start with a really simple textbook example of object-oriented programming without roles. Everybody has seen this example on some slide desk or in a textbook employee is a subtype of person. Good model? So when you instantiate, when you create a new object so when I was created did my mother say create employee? No, she created a person. And so that means I'm a person, I'm not an employee and will never become an employee. That's so bad, I want to earn some money and I want to do some good. So the first thing is that the choice of type with this kind of model is a one-time choice at time of creation. That's it. And the opposite end means that if I lose my job I'll be dead because if the employee is gone there is no more person. So that's very bad for me. So I would like to rephrase this and instead of inheritance use what I call a plate by relationship. And this again assigns the two stereotypes of a role and a base. And the point is that explaining the role thing doesn't work by just looking at the class diagram. In order to explain the roles you have to look at instances. And this is where dynamism comes into play. Here's an instance of person, he's Joe. His name is Joe. And some time during his life he enrolls at a university gets a matriculation number and now he is a student. Which means he has two properties now. He has a name by way of being a person and he has a matriculation number by way of being a student. While he's a student he's running out of money so he's looking for a job. So in addition to being student he now is an employee. Salary, whatever currency is not that great at this point. But the first thing we learn here is that, oh he may even keep the job after quitting university. How's that? So what we learn here is that with roles, using roles instead of inheritance you have the dynamism that you can attach roles to an existing instance and you can remove those roles. So you can add and remove properties from an object. And you can even take a second job. So Joe is two employees because the first salary didn't really suffice. Probably at one point in time he doesn't even need that second job which means you can even create multiplicities that are not possible otherwise. By playing the same roles several times you have the same property multiple times. We'll create some need to be careful but we have all, we have these two additional degrees of freedom, dynamism and multiplicity. And just to summarize the language construct that we use in order to achieve this role concept on top of Java we only have three new concepts in this language that are needed here. We declare a role just by declaring the relationship as a plate by relationship. It has some resemblance to inheritance but the semantics is different as I said. But the syntax is just at the same location where you would write extend, just instead write plate by and that defines the role playing relationship. Which means it does not statically connect the classes. It just is the possibility to connect two instances. I will have separate instance of watch display and a separate instance of stop watch and they together are one conceptual unit. Second piece of syntax I have is what we saw as a call in method binding for method call interception. The error going from right to left symbolizing this is going into the role and we have these modifiers and the opposite we only briefly saw is what we call out bindings which is simple forwarding or delegating. It could be either if you know the tiny difference between these two. Which just means I don't have the functionality in the role but my base part has it so just reroute the method call into the base part of it. Which would be almost useless or doesn't bring much benefit unless there is one thing that a method, the call out method binding is allowed to do which you otherwise would not be allowed to because it can disregard visibility rules because the employee role and the person role are considered to be conceptually one thing we decided that the call out method bindings don't need to pay attention to private to protect it. So I can forward to any method of my base class disregarding any visibility restrictions. And now here come the moralists because now I'm breaking encapsulation. I'm invoking private methods from outside that class. And now people will enter heated debate is that good or is that bad? Which are moral terms. And so the people living in the city, they say boundaries must never be violated. Period. It's out of discussion. Finally enough, the fair side people will also say, oh, this is not good. You shouldn't have the boundaries in the first place. So the solution I just presented will not appear morally good to any of the people from either camp. Do I care? I don't care about the moralists point of view. What I care about is just realizing that I gave more power to the developer by doing this method called deception by invoking private methods. And the only thing I have to add now is that I have to realize that with power comes responsibility and that these powers could of course be abused if you are malicious. But at this point, the best we can do is in addition to the power also equip the developer with some means to controlling this power so that it can be statically analyzed how much damage is done by breaking encapsulation if you want to put it that way. So I want to control the roles and I want to do this in a modular way. So basically I'm still a city person. I just want to have a few exception where I can do a few more dynamic things. And in order to understand how I can control roles, we need one more concept. Consider he is a base class person and a role employee. And so for example, the role employee intercepts any call to the method get phone number because the employee has an office phone number. So if you ask the employee, you should answer the office phone number not the private phone number. But if you're out for a date in the night and you ask for a phone number just because you're an employee you answer your office phone number doesn't really help to set up the next date. So maybe it depends in which situations should I answer my office phone number in which situations should I answer my private phone number. And the one thing that's missing here is that this selection depends on context. And the context of being an employee obviously is that I work at a company. So there's a container for the role. The role is only valid if there is also a company that employs me. And this is something that holds for the concept of roles in general. Roads are a concept that is defined relative to a context. And in object teams, now we come to the name of the whole thing, we re-ify, we model those contexts as team classes which are kind of big classes with the roles as in-app classes. And in order to equip developers with this possibility to control my roles all I have to do is add one switch to that team. So you can turn the enter team on or off, activate the context. What does it mean? Well, each team has this context and the state of being active or not active and the sum of all the team states comprises the system state. And whenever a method called get phone number is received we relate this to the team instance and then we ask, is that team active? Is the context active? And if yes, then the method called interception will apply. If there is no active team, then the private phone number will be answered and we just don't know about any roles because we don't know about any context that would hold those roles. So that system state of teams being active or not active contributes to the dispatch. And this is the main way how people can control roles. And there's several ways to enable or to activate teams. You can, for example, configure that throughout my application a certain team should be globally active. And that would mean I'm only considering things relative to a company. There's several ways for an application where you can pass a configuration file or with the integration into Aquinox we can use an extension point for declaring these things. More interestingly, the scope of activation can be selected and one thing that's very interesting, very powerful is that you can activate a team just for one thread or for two threads or three threads. So individually so that in one thread the application behaves completely agnostic of any teams and roles and another thread it is modified by a team that is active in this thread. Very powerful or you can say it should be active for all threads or you can programmatically just turn it off on at one point in the program and turn it off at another point in the program. Just call it sending activate or deactivate method call to the team. Time to show some of this controlling and so the question was about hierarchies and yes, we support all dimensions of hierarchies that you could think of. You can apply inheritance to roles and to teams and you can also have cascades a role played by a role played by a role played by a base thing. All this is possible. So all these combinations are possible and now let's look into our second example. First of all, it highlights the way how we can work with the black box component. So here's a Java file that implements a very, very simplistic flight booking application and so it's embarrassingly simple. All you can do so I can for example book a flight to Hamburg and all it does, it tells me what's my balance afterwards after withdrawing the price for that flight and I can also add a new passenger and typically my new passenger is called Joe and Joe is a millionaire and what happens, nothing happens only that Joe appears in the passenger list, right? So this is a boring application and first what I want to show here is that without modifying this Java file, I can change the application. Let's first have a look at source code quickly, not all the classes that we have. So here is a team called Flight Bonos and that's the adaptation I want to do to this application I want in addition to booking flights, I want to allow clients to collect some bonus points for each flight they book and this implementation is simply done in a way that I have a role class subscriber where I only show that the subscriber class is played by passenger. So every passenger that's traveling with this airline can be a subscriber bonus points and what are the items we collect bonus points? These are the individual segments of a flight. So I flew from Berlin to Frankfurt that was my first segment that will earn me some bonus points and one tiny more thing I want to show is that somewhere here's a GUI controller the purpose of which is just to connect this new workflow this new business logic into the UI of the existing application and inside this I just declare that whenever a new passenger is added to the passenger database I want to put up in your dialogue whether this passenger should participate in the bonus program and that method is implemented essentially by instantiating the previously shown team class flight bonus specifically for this passenger. So there's a context for this passenger and only this passenger has this team instance and so for one passenger the bonus system should apply for others it should not apply. So in order to make this adaptation active at runtime I just edit the run configuration and there's two things in run configuration for regarding object teams. First on the runtime environment page we also have a new check box to enable the object team's runtime environment but more importantly there is a new tab in the run configuration where we can declare that this particular team should be instantiated and activate the private application startup time. That's all we need to do. Apart from that it's the same application as I previously had and running it looks like it did before but whenever I now add my passenger Joe, the millionaire, here's an additional question, pretty small, it says register for flight bonus. And I say yes and if Joe books a flight from Berlin to Hamburg then before showing the new balance I also show that Joe earned 1000 credits for this segment of flight. Okay, so before the next part of the demo I have to place a little man behind the curtain. Please don't have a look at this. So I run the same application again and in order to come back to my story of near misses I adjusted the application so that I have the flight booking, I have the bonus earning but one thing I still don't like so when I click new passenger, the dialogue doesn't appear on the place of the screen that would be most suitable for the application. Couldn't the dialogue just appear at the center of the parent window? Wouldn't that be nice? It doesn't. That's just the application has been implemented and now comes a story I will not stop the application. I will change it. How do I do that? So application is still running. I add a new team class, say the package is example.UI and I call that team class Placer. Inside the team class I create a new role class. Call it placed window and that role class is bound to the class window from AWT. Inside that class I want to work with this pack method. I create a method binding to this pack method. I call my own method center and I want this to be an after binding as we saw it before. Wait, now I'm instructing the pack to invoke a center method but I don't have a center method. So I create a center method and in this method I want to set location relative to get parent. Wait, content assist offered some methods which are not here. So my content assist problem. No, content assist is smart enough and even the compiler could if I wanted to infer that it didn't mean the methods from my class placed window that probably I meant the methods from the other part of this thing which is the window. So I can make this explicit by a little quick fix so that what has been inferred by the compiler already is now put in carved in stone that I have forwarding from get parent to get parent from set location to set location. And yeah, that's all I need. Hmm. Or does it help the running application? I have a scan button. The scan button simply looks at the bin directory of the running application and looks if there is anything modified. Oh yes, I found a new team example UI Placer and by the way I activated that team. So what I now create a new passenger the window appears in the center of the parent window. So I adjusted that black box not only at compile time I adjusted that black box at runtime. That's what I call runtime specialization. The placed window is a specialization of window that has been created at runtime and it could even have effect onto instances that have been created before. So a very quick look at the technology behind because you may be curious how could I modify a running application. Technically method called interception is implemented by bytecode modification. And typically we do this at low time. Recently I added even the more static variant as build time bytecode weaver but that's boring but what is new in the current release of object team at that we have runtime bytecode modification. So bytecode modification even of classes that have already been loaded. It executes on any standard JVM if you have a plain application just need to pass a Java agent. If you're in an equinox setting we're only using the standard weaving hook from those GI standard and that's all that's needed to make a Java VM execute object teams programs. Very briefly about the state of object teams in Neon because when I say we recently added this runtime capability that means we have two bytecode weavers actually. One was called object teams runtime environment had matured over more than 10 years is able to do these changes at low time and the new thing has a little D and the name additionally it's the object teams dynamic runtime environment which can do low time and runtime weaving. It is near, it is feature complete but it doesn't have the 10 plus years of maturing so it probably still has a few bugs just won't let you know if you play with us but in terms of dark footing the object teams development tooling itself basically is the JDT with a few adaptations and guess how we do the adaptations using object teams and starting with Neon these adaptations are done using the object teams the dynamic runtime environment so even in our own environment we may by the migration from one weaver to the other see a few rough edges if you play with it and see some problems please ask in forum report the bug because as quickly as possible I want to get also this new technology to the state of maturity that we had for the old one which by the way the old one simply doesn't work for Java 8 because we use a bytecode library that doesn't support Java 8. Summing up what's the effect of all that that I said to the different phases of software development if you are essentially in the static word word where you use building blocks that have boundaries so if we want to support reuse in the static word you have to first create a variability model either explicit or implicitly in your head and if you want to add a bonus point you may add some extension points to your component that you're putting on the shelf during composition of an application you just wire and configure these building blocks and what's new with object teams is that even at building at composition time you can still adjust existing components during deployment you do more or less the same thing and you can still do unanticipated adaptation so for regular Java application after the development phase everything would be frozen with object teams you have unanticipated adaptation during composition of the application even during deployment and even during operation of a running system starting with object teams in the end we have the possibility to make that square red peg to fit into the round hole and to make the application exactly as we wanted no compromises with regard to functionality with regard to requirements you can make it exactly as we want no matter how many black box components we have and so we don't want to repeat and we don't want to make compromises and with this I conclude with a reference of the URL where you find additional information thanks for listening and I'm happy to take some questions with their question the arrow saying so yes so this syntax was designed many years before lambda's and it creates a funny situation for the scanner because lambda also has the same token arrow token but the context where the token appears actually helps to make this unambiguous but you'll write the same token can be two different keywords depending on where you are but it works similar to aspect J so this has been developed initially in an academic context of aspect oriented software development and basically object teams development started a few years later after aspect J started which basically gave us the opportunity to pick up all the good things they have and avoid the parts of aspect J that create problems so yes there are similarities I believe object teams is both more powerful and more secure yes of course this dispatch has some unavoidable performance penalty very much depends on how frequently this appears and I believe that just being able to write an IDE that performs pretty well with this technology is proof that this is practical you should just be careful what interception points you choose if that's a point that's called millions of times per second then on the current JVM this would be a problem some colleagues from the aspect oriented field have picked up this challenge exactly and the ideal answer would be that JVM should be aware of this additional kind of dispatch and then it will be million times faster for the time being this bytecode weaving is the best we can do yes you have to be aware about the penalty but in typical application it's just not noticeable how do we handle exceptions? well there's actually some quite strict rules as I told I'm keen on rules and so there's restrictions to whether or not a roll method can throw exceptions if it throws a runtime exception that will actually percolate check the exceptions are not allowed to be bound because then the base method would have to declare the same exception as well yes so that's basically the story if a roll method throws an undeclared exception that will blow up at unexpected places so roads should be a little more careful about runtime exceptions than other places so there are different situations of course so it's regarding the resolution if you have multiple roads and if you have hierarchies so one of the rules we have is that we control it with the order of team activation so the team that has been activated first has highest priority and then only which means highest priority will be the first of the before binding and will be the last of an after binding and will be the first also of a replace binding and so that can decide what the others will do so under control of a programmer in which order teams are instantiate for example this is one thing and if it's within the same team we have precedence declarations where you can say this binding has precedence over that other binding that's basically the two mechanisms we have inside so can we see the interception in the base class and in fact there is two things to see at this base method it's in the IDE of course the source code doesn't have it because the source code doesn't know and here is a marker that a call in method binding applies here and it actually has a context menu which could take me to the role that adapts this and regarding both this and the previous question we actually have a warning that tells you multiple call in bindings are affecting method advance because I have this digital and this analog I have a marker that tells you in the source code advance method has two call in bindings have you taken care of presidents to raise awareness of the situation so all this is done by markers in the UI in the editor because the source code simply is agnostic of all these things in an asynchronous environment well it doesn't add additional synchronization needs because each binding just happens well so first of all I said you have the choice whether a team should be active globally or only for a particular thread so if you do not want the bindings to interfere with some method standing that goes from one thread to the other then you will simply activate it only for particular threads if you want the team to affect also asynchronous communication it can do but I frankly don't see any complication it adds to that scenario so that particular method that you're intercepting at the moment it is invoked it is executed at that moment the dispatch takes place so either at the moment the method is entered or at the moment the method is exited these are the two points that we're intercepting and so we're not adding more asynchronousity so it only shows currently only highlights one direction the interception part is highlighted in green the opposite direction going back from the row at the forwarding to the base thing is currently not highlighted but I may actually show you the static variant of this which is basically the same story no wait a minute I should start use a different starting point so if I look at the get value method the call hierarchy which basically corresponds to the call stack shows that there is interception I know this is a forwarding this method can be called using forwarding and that update method can be called using the interception so here we have it integrated in both directions debugger currently only highlights the interception part because at runtime that's even more important to highlight but it's a good suggestion to also highlight the forwarding back into the base thing we'll think about that, thank you I can't hear you in the web application so whether or not you can use it in a web application it's basically a question of the container that runs your application and so if you're happy for example to run OSGI in that web server then we have mechanisms to directly use that otherwise you would have to control the launch of that container that launches your application and then you would have to add a Java agent to that container launch otherwise if there's other containers that you're interested in using and if it has some other means for hooking into the class loading it should probably not be too hard to write a specific integration into each container but basically it works for every Java application and if you control the container you can make the container handle any object team's program as well you need to be able to hook into class loading, that's the point we need okay I guess next speaker should have some time to prepare thanks for listening and happy