 Hi, welcome to the last talk on Saturday tonight in the blue saloon at the gpn-21 JavaScript or Java has some nice Functionalities and one of them is those little tiny agents. They can do a lot of work They can help programmers engineers to make the work easier and fix things and Make code more beautiful Johannes is showing how this works and how he uses it in his daily work at SAP he's a J. He's a Java developer and It's going to explain those Java agents I See some tools from the hardware store. I see some materials some screws some pieces of wood I'm very excited how he's going to use this in his explanations applause to Johannes Take us away. Thank you for a kind introduction. So Without further ado, I want to start with a small example. So consider I'm no not a speaker or Java developer or whatever But I am a frame beller. I come to people's houses and I want to build frames So essentially a client came to me and said I have these Have these precious images because I like them at my home And I want to have a frame and I'm like cool. I'm a frame. We're like and both frames They come to him and say like here's the what cool and I think like yeah I probably need need screws to and I need some nails to and I need a drill bit so maybe put a drill bit and I need a Power drill because like I want to drill these these these pieces of wood together and Polly that's also good and I need a hammer to put it on at the end So I I'll need a hammer. There's there's one hammer in so that's that's probably fine. I just take it with me. So but and then I come to a client and the client is like You only wanted the hammer and took this with you because essentially I would need and I took this all with my Small carriage and drove it through the whole of the city, but it could fit in my backpack If I just had like pulled out the hammer pulled out the power drill pulled out everything So essentially What I want is I want to pull out just the things that I will need so in the end I would just keep a backpack, but the software developer. What does the software developer do? He uses something like spring and spring depends on like everything the whole world is like the software developer things like Yeah, I need a collection. So Polly and use a patchy collection But in this one instance the eclipse collections framework is tiny tiny tiny bit better So pull just in the whole eclipse collection framework and guava has some quite nice P-map So Polly just pull them in too. And so in the end we we got the large large large Application which has hundreds of megabytes of dependencies and it's like without all the power tools We only needed a hammer. I Put out a real a whole box of things where we have screwdrivers and everything which I never need but as a software developer I don't care I pull the garage with me if I can I pull the whole house and even In some languages I pull like the whole city with me, but as a carpenter I really cares why don't we care the thing is it's bit harder. So We probably don't need all this. So if you now consider that we are that that we suffer architect So if we were built buildings, then we'll be like at the beginning right now for tower That's nice, but we need a clock in the city somewhere. So, yeah, what take a clock put it on then We need some housing. So maybe put some housing on top. That's fine. And then we need we need to carnival We need some attraction just put them on and that's like thank God not everything is so fair if it would be it would be quite horrible Because in the end and that's a quote from a paper By by sort of a lero the software grows and grows and grows naturally and in the end it accumulates Not only like cold lines, but also box and security risks And so it's a major major effort to deep plot the software So but but how do we do this? So there are different types of deep-loading essentially. We have dynamic and static deep-loading tools Depending on like dynamic is it runs besides the programs and static is we pre-analyze so for static It's quite easy and we can just use cold analysis. That's okay I try to do PhD in this field. It works, but don't use reflection reflection is for colonizes a Magic bullet that kills it because the first time you have like reflection that gets a string into it and the colonizes is like Yeah, I don't know anything about the string then the reflection could Access every class and probably also every method. So this has this status has its advantages Then you have dependency analysis tools that but that's a whole non-topic and with dynamic tools You have either coverage base. So, you know coverage base Testing your coverage testing You run your whole test suite and then look which methods are used. That's quite interesting and there's also like profiling based And that's why I come on but because I'm like a profiler guy. So I work at SAP. I do some profiles according to these slides to them on And I work at sub machine. It's Large it's a quite large open source team with like 15 people working at the open JDK at SAP we're the third biggest contributor there and For example, if you want to know something about power PC We have the lead on power PC for JDK in order JDK 17 updates maintainer and therefore of course stickers here with our nice sub machine So what I regularly do when you don't do talks and don't work on like the bloating I work on profiling for example creating profiling you eyes creating helping to create profiles and also working on like internal stuff in the JVM So, how did it came to to work on profiling? It's it's simple I was at a conference in in London in March and someone asked me like hey, you have you have this article on Hacker news that's quite high up and it was an article that I wrote under the channel It's called writing a Java profile and 24 lines of your Java and then he said like hey, there's a paper out there It's called coverage based the bloating for by code any opinions on this? Have you thought about the bloating any time and I was like You know blowing art sniping where we're in this famous XKD someone asked the Physicists and complicated question and the train comes by and crushes him I was like the same like you know the JVM. Could you help us to bloat using ancient and both of them? I'm like But it it was good. I was in a bed in London. It was small London is an expensive city So I didn't get hurt. I'm here now So because it's not like existing tools have problems coverage based tools have problems all these tools have problems and One of them they're quite complicated. These are tools Written in described in research papers with long abstract with long everything. I couldn't understand I could understand him Yes, but I couldn't really Understand why they should work properly because they were just too long the implementations that I found on some tools Well, like thousands of thousands of lines of code and you could ask are they bloated too But that's another opinion of the bloating to nothing of the bloating the bloating code So essentially I thought I could just write my own because how hard could it be? People doing their PhDs on this topic, but hey, I have two days of leisure time in London. So maybe and Maybe I get out a small blog post on it because I block like every two weeks And so I thought hey, I need a blog post maybe do this and so the person that asked me was actually a person from SAP security research So it was interested. So of course, it's a prototype what you're seeing here So we first reduce the problem because that's the first step in everything that you should do. So Of course, we could find like unused method and anything, but that's quite hard and my main idea was Many user users or when when the code uses a method from a class then it's highly likely That all the other methods are probably also used In there somewhere and also depending on like how how methods of this class are called It's how likely that many of the other methods would be called because otherwise you could quite easily catch this with Static tools. So I thought like hey, maybe it's okay to just find unused classes and that's the whole idea here This makes it far simpler. So To find unused classes, it's quite simple. We first have to of course know the Classes that are there, but we can just look at the trial and see yay This class was loaded or yay. This class is like lying around in the bytecode. So we know this but how do we know An unused class any ideas and use class and because we can then say oh, we know the use classes We know the of all classes Then we know the unused classes any idea how we could easily check or see that class a is used or Recalled at runtime that the class a is used any idea here My large audience Could we insert there's some code? Yes So the idea is essentially in the back for those who didn't hear it It's essentially yeah do static analysis. That's cool But we are here dynamically because static analysis has its problem as I explained before any ideas how we could do this Yes, so the answer was essentially this that's cool. It was like hey, you're doing a talk on instrumentation So maybe you instrument a class and yes, we have some pride people in the audience That's that's always cool. So essentially what we're doing with static initializes because they are used a lot of time They called a lot of times for example, and they Use and they like to use the language specification because that's a great source of truth in many Pediatuments that you have with your colleagues at small companies like is this an expression is the dot an expression You can look in the travel language specification and Tell the other person that it is or it isn't and nobody cares, but yay So essentially here when when our static initializes called essentially every time a class is used and every time I try class of a class is used and that's pretty neat because that's essentially what we want And that's easy because we can trust like instrument and that's fine. So The problem is now Interfaces question to the audience is this legal code replace this code here Who of the audience thinks yes, this is legal Java? Who thinks that isn't Java? Who the majority says it isn't Java and that's cool because it's right It's forbidden in Java because Java is like this a little known language that has some things written in the Java language Specification and other things written in the bytecode specification. So this is allowed in by code, but it isn't allowed in In in Java at least as far as I can understand but a cool thing I only care about by code because By cold is far cooler. Just write everything in bytecode doesn't lead to any maintenance hell at all It's like writing assembly assembly was time of colleagues that wrote like systems in assembly when they started They started before I got by before it was bombs on it was interesting. No, um, the thing here What we then get is that we have to deal with interfaces a bit differently because the problem is when an interface is like accessed we don't access also the the stake initializes for the Parent interfaces aren't called so we have to deal with this, but that's quite feasible We can just walk the the trees the inheritance tree. So essentially what we get we get the plot We got the classes found in the bytecode by the instrumentation on the one hand. We get some recorded classes Also, so we yes, we have and we got some recorded classes these that are like used there and then in the middle We have the plot classes here and then the use classes The important thing is that they are used classes that aren't in the bytecode directly aren't in a trial for example Lambda the classes for Lumnas or classes. They're generated dynamically like by mocking frameworks or poorly also by spring But what to do with this information? So one idea would be to just remove the plot classes. This is interesting because it drastically reduces the size of of jobs even With this example it can even with with this quite course approach that only deals with classes We can reduce it so the size but the problem is when we move it and then we run it in production and then someone accesses the class by chance because we only We only being dynamically we only recording new classes dynamically so we don't actually know what classes could be used It also in there in rare circumstance or some other class could be used that we just didn't hit in during testing So the idea is we don't remove it, but For these classes that we know shouldn't be used so that we can ignore them for example for security warnings and else We can just long arrow and then decide on the arrow or decide in this code here what to do with them for example we could like Crash the server or we could alert someone or we can stop it or pass it to another system And it's quite nice because then we we deal with the bloating from a security perspective Of course, it doesn't reduce the size of the actual binary, but we have to decide where we want like Real size reduction or whether we want certainty that the server doesn't crash in production So in production, I would like servers to have a high uptime So now for something completely different. Yeah, it's implementation time because the implementation is the thing that I'm interested in I'm more an engineer that I'm scientists. So the structure here of this code is is quite large because it's an interesting problem, but essentially what we're doing we're recording first with our agent all We're instrumenting recording all classes that are used and then produce a file called classes.txt or something else Then use this information to either put it in the agent back and so say The next time you're instrumenting, please instrument these classes that we know shouldn't be used with this like log or we use Or we use Some some code that just removes these classes. The problem is that we're string There are some problems with getting all with instrumenting all classes I don't know why maybe some class loader shenanigans Spring is interesting because they use lots of class they they use some class loss. They use some reflection. So for this we then Instrumented directly. So we instrumented drawer and not at runtime, but that's essentially the same way We're doing the same but just before Running the code and else at runtime So how is the agent structured? We have a main class. Of course, that's like the entry point We have done a class transformer That transforms classes. This is then called by the every time a class is loaded And then we have a store that stores this information and produces us with the information which classes are unused which are used So but We have one problem with the structure can consider this here again with all class a that that's fine class a lives Lifts here in the same space as the store So it's apparent that when we instrumented class a can access the store the problem is now With with class string class string is like an internal class. So it cannot really access the store class When we add it because of the class load hierarchy, so Class load is something that loads classes So we have a few of them and they form a hierarchy. So for example when The child class loader doesn't know a class. It asks this parent class like hey, can you load this for me? And so we have to boost our class loader with everything like strings and Strings and integer classes and so on and then we have to platform classes which contain more of the broader JVM internal classes, and then we have your app class loader and the promise And then probably some more and and the problem is here that it's quite easy It's quite feasible that something from a class uploader From from the app class loader can access other classes in bootstrap because we're doing this already We're accessing from our application like string integer and everything all these nice classes but the problem is the other way around is difficult because like The bootstrap class loader can't ask his parent class loader like give me this class because the parent class loader is like which class? So there should be a way around this and of course We can just tell we can just package the store because that's the only thing that we will need that the bootstrap Glacier will ever want to access Into a runtime jar and then can just ask the bootstrap loader. Hey, please also look when you didn't find a class Please also look into this jar, and that's quite nice because then Everything works and How can we implement this essentially? Every Asian is passing an object of class instrumentation, which has an aptly named method Append to bootstrap class loader search. Yes, Java people like long names But I think when you ever wrote some string application You know that you can only by name tell that something is belongs to string And so essentially we can just append it and that's fine But now back to the agent itself How can we write an Asian so we know main methods here in Java? For example, we can use the main string arcs. We can also like put the scrap records behind the arcs because yeah, it's Java and With the new Java version Java 20 mon. It's also possible to write this but this doesn't really fit agents because Agents can be attached either at the start of an application or later Because the agents are just like simple tools That run besides your code and so there's a method called agent main That's called when you attach it later and there's a method called Pre-main that's touched at the beginning and that's quite nice because We can distinguish these but promise here, of course instrumentation is missing But there's a variant where it's also get passed the instrumentation and instrumentation these these objects contain a lot of Methods that are useful for instrumentation. For example, as I told you before like to a plant to glass loader to boot glass loader search or Methods to get to re-transform classes, which is is quite nice. So essentially what we're doing We are passing the option somehow We are pending to the bootstrap glass loader power search path and then we're adding a transformer and that's the critical part This allows us Transformers as quoted here the documentation Has a method called transform And this method gets parsed every gets gets passed like the class loader that the class belongs to the class name a class object When the class is like re-transformed because we can either Transform a class that we loaded. So this class loader this class transformer is is executed whenever a class is loaded and If we set it to do so when we call a class to be Re-transformed which is quite nice. And so essentially the important parts are here class name and the class for buffer It's just like the bytecode of the class and then we have to deal with this. So What I found through Some some errors they got It's really healthy if you just throw away a lot of classes and don't Instrument them at all because it makes life. So it makes life so much easier, of course You could later when you put more effort into Into its transform them, but for example, it's helpful to not transform any of your own classes From the agent because like you could end in quite nasty endless loops And I found also that like the JDK internal Libraries aren't a traitor instrument and also the Sun part which is like the JDK internal internal things are not that great and Sadly it had also to pull out The Java package just because I got so many hours. Yes, it's possible to deal with this, but no not in the Time that I got for this for this tool. So essentially how can we then transform the bytecode? Yes, we could write bytecode. I like bytecode. You probably too. It's the nicest language ever produced The only promise you got lots of bugs when you write it and I tried to in turn my time doing my PhD I tried to analyze bytecode. I wrote a lot of it And it was interesting and the promise you probably don't have time and you don't want to Tell someone that reviews your code like hey, that's a cool idea They're all like this many custom bytecode. So essentially you grab the next best tool and that's Java assist It's a tool that belongs to the jboss family of tools Just it stares as it says since it's a long long time. It's one of the oldest Tools in this area and essentially it allows us to write something like Please create me a class initializer on this class and please insert this Java code And as you see here, you can just write Java code. That's quite interesting and quite fast and To write but of course you pay the price that every time you transform it Java assist library has to pass this Java code, but usually you wouldn't run it in production, which is cool and Usually also it doesn't really matter on that much. Hopefully you don't have too many glasses But in the end you're the bloating. So you probably have How to use it? It's quite simple I use here the pet spread clear the spring pet clinic and you just call on Java agent But saying by passing it to Java you can pass it some arguments for example here where should it store these classes And then run your application and then you get something like this you get For example that the class pattern later encoder is used and the class drawer and configurator Whatever is just loaded and you can then use this to pass this back again into my instrument Hey into my instrumental or into a code that removes it and here I just instrumented it So it locked classes that weren't previously lose and then worked on the pet link click the way it clicked on some different buttons and then it told me like hey these glasses are not allowed and so that's the logging and That's that's for the bloating here, but they are of course other application of other applications of agents So what we'll recommend when you have a small problem when you have a problem and work just just try out some engines Just try to write your own agent and for example, you could use it to write a profile quite easily like in around wonderful lines of code and That's all from my side here. Thanks for being here. I'm part of modern Twitter and you can you can read Every two weeks a nice blog post and Java and also some of you might be here tomorrow When I'm also giving a talk on in on do you trust your profiles? I once did too. So thanks for all your audience here any questions Do we do we have a microphone to pass around I think that makes it easier so I don't have to repeat all this all the questions Test yeah Could you recommend a good introduction into Java agents? For example a tutorial is of course I could remain I could recommend my blog posts on this topic I think typically there's some good ones from Oracle and also there are some good ones from badung out there I would just recommend going to my article. I linked these there So I think the best introduction is just work on it. So just so just to pick another agent that does something similar and Copy it because my code is MIT license. So you can just grab it. So that's an example for an instrumentation agent I also wrote a profile over just like an example for Application it runs alongside So I would start with this and then just modify it. That's the way I'm doing it So when I created this classroom from my first approach was like I copy my old code into a new project rename it And then worked on it And then I had some error messages. I googled them and that fixed it because just take overflow That's how you do professional development Also in the open JDK and I want to add that in the beginning I was introduced as Java developer That's not that right. I'm an open JDK developer. Yes, I do sometimes write Java, but I usually Write the JVM. So I'm kind of a Java developer But in a different sense that many people so I'm working on Java not with Java. I like to write Kotlin That's a nice language. So anyhow, yes in the back. There's also someone who likes Kotlin But the sadly when you work on OpenJK, you have to write Java because in the OpenJK people like Java I don't know why maybe because it's like the open Java development kit, but that's a whole nother story Any other questions? Yes Then again Do you know how your tool performs with annotations? Who interesting so If I'm honest, I didn't look into this it might be interesting Yes, because annotations and the whole part of like preprocessors that add to your code That's a whole different class of errors and that's a whole different topic I think with the instrumentation agent Shouldn't be that problematic because we're still getting all new classes when an annotation creates a new class It's still interesting, but I think there there needs to be some further research so that's only a prototype and There is some that there are some people who you who try to work on my code and look into my code and Do this more properly. I just spent like a few days on it and so yeah, hopefully there's something I think in the back is a question or You previously said that The time passing the Java code you gave to the bytecode generator was actually annoying even in development Going back to annotations. Have you considered doing annotation using annotation processors to actually generate the bytecode in the compilation step Because you can use Java doing that and then insert that later on Yes, I considered using like preprocessors or tools like this or just tell Java assist like Please give me the bike or please give me like the thing that you parsed and Deal with it. I think Java assist probably allows it because Java assist is used by so many applications So I consider this but the problem in the end was I didn't want to spend too much time because it's still a prototype And please don't use this in production. It might kill your application in the whole world I don't guarantee you for anything. It's just the older tools that I'm writing like also the profile that I wrote Which helped to begin this whole story They are for educational purposes You could use them in production if you really sure what you're doing with the profile I'm sure that it's kind of working. There was even someone in in Milan where I gave a talk on this He was like, oh, we I'm a consultant at our company where I'm currently working We cannot use a profile, but I can insert codes that can just insert your Java code your your prototypical Java code to profile application that was like So Yes, you could maybe work on it But I think when you like to work on this and make it more efficient place gone. It's MIT lessons. It's on get up and I'm happy for any contributions So many questions for my large audience Yes, okay, is it possible to instrument methods in Java, too. Yes, so so what you can do here The two things for for one you can of course you get here class So you can add some code to methods for example here. We're essentially doing this We're adding methods. We're adding coaches that they can initialize a the problem is that some classes cannot be extended this way Good example is when you have native methods Methods implemented in in C++ code. They are a few rounds because Methods like system punk current time millies where it got into a real rabbit hole to see which time source it uses Yes, it uses a different time source than system punk nanotime But that's a whole different story. So There's some efforts that you cannot extend So that's quite problematic and the other thing is that here in this example It wouldn't work that well because method chronology was to find more me But yes with regular Java methods, you can just work on them as you like So you could even I think you can you remove methods? I think you can't but you can probably just remove the body of a method and replace it with Throw help so and this was also an idea that that came up during my research that I could just Instead of logging all it instead of logging at a class like the initializer I could also just use all methods and Replace them by throw new runtime exception by didn't do it in the end as I said, it's just a prototype Try it out. Maybe it gives you better examples better results Wouldn't it be possible to take the hotspot optimized bite code and compared with your results? So maybe they're more dynamic analysis results from the Java internals direct for one thing I think as so as far as I know the hotspot. I'm not a developer when I have hotspot Questions I asked some colleagues because I've colleagues who are like 20 years in the field, but You don't have the bike or the bike code isn't really optimized the bite code is transformed in as far as I know into a different set of Instructions and this is then optimized because the bite code is Interesting for writing it down. It's a short format, but it's not a great for actually optimizing just ask the person Next to you who probably should should know something about optimizing. I hope Yes, there's a question in the back How does this interact with Java 9 based? Optimization because of Java 9 and later with the proper module framework You can even split the JVM and build like the one specific split of the class and modules you need How much of that could you already use to? Throw out a large part of the classes that you would interact with you could use it Of course, you could use it especially for all the JDK related classes the main problem is Does anyone use the module system this way? So that's the module system most is like rage Revolution, but nowadays I just see it as a hurdle for people coming from Java 8 to Java 11 So I think it's it's no secret that like many people still use Java 8. They're even companies Eddings having support for Java 7 and they heard of cases where Java 5 and 6 are used So I think the module system is a whole new topic and the problem is on the module system There isn't that much documentation and I think By my being correct that the module system is just too complicated for people to use so Yes, you could use it, but no It's far easier to just throw out the code like this and also as I said the module system is restrained to the whole JDK it's Yes, you can use it for your own applications, but I'm unsure whether for example string has fine-grained modules and the whole thing about how fine-grained it should be it's it's hard and Where I encounter module systems most is like when I want to use in non Java 8 so in higher versions Some some internal Java API's and they have to add like hey, please open this module for me And it's especially weird when you have like bugs in and build systems for example I had once a bug that was quite annoying. I wanted to add like modules. I wanted to use to to an Eclipse-based project which use Maven Tyco and I couldn't add for whatever reasons these Add open module or whatever statement So what I had to do was interest was to prefix it with a non With a normal option like minus version and then the thing because then Maven Tyco could parse it So that shows you that like still even both systems have sometimes problems with with this And I think I proposed I told you Maven Tyco people like there's a problem. Could you please fix it? I think they fixed it now, but I'm unsure. So yeah, you Maven Tyco any other questions Then then thanks for your audience here if you want to read more on this whole topic. I've I've got an article Out there and just ask me when you have other travel related questions and come to my talk tomorrow at I think it's at 1 o'clock Then goodbye and good night