 So Fredrik will be giving the next talk about using Jaitan in practice, so please welcome Fredrik. Thank you. Yeah, so I will be talking about Jaitan in practice and go through some examples. It will be quite high tempo, short on time, much content, but I'll start just with obligatory bit about me. I'm a software contractor, I do lots of Python work, I've done lots of Java work, if you count the years and hours I've definitely done more Java work than Python. And during the years I've also used Jaitan in corporate environments for different reasons and different situations. And it seems that in the Python world the option to do this is not that very known, so I've been trying to market it more or less as a way of making your Java stack more enjoyable. But as software developers, all of you are, and nobody will remember me as a software developer, the hook for remembering me is that I live on a boat. I am not a software developer, I am a software developer who lives on a boat. And if you think that would be hard, you should also consider that this is the view from my office. So, the archetypical Jaitan intro. You download the jar, you can run it, or if you run the installer you just do Jaitan and you get a Python repel more or less. The main difference being that you also get the JBM information when you start up. And you can do hello world. A little bit more interesting is that you can also import stuff directly from Java and then you can print hello world again, more or less. And one thing that's really interesting if you haven't seen it before is that in this rebel you have full introspection capabilities from Python into your Java code. And this means that you can actually actively use the repel to explore Java code. To me, this is a huge thing because I spend lots of time in the repel while doing exploratory programming in the beginning of projects and so on. And I basically would spend so much more time if I didn't have introspection. Or, of course, Java has introspection. It's just nowhere near as convenient. So, my first example will be the first time ever I go against the general wisdom and do a live demo on stage because doing servlets is sometimes useful because you can kind of shortcut away the entire edit compile test deploy loop that you get when you do servlets. And it's also really, really convenient. So I will show you how much work needs to be done. I have downloaded the latest version of Tomcat. I've also downloaded the latest version of Giphon and put the jar into the lib folder of Tomcat and started the server. And then I've created a new servlet. How many have created servlets? Okay. That's quite a few, actually. So the only thing I've done is create a folder with a web inf, which is the configuration for servlets, if you don't know. And I've created a very small web XML. This is basically ripped right out of the Giphon documentation. Because Giphon comes shipped with this pie servlet, which basically is the only thing you need to do Java compliant servlets. And then we just set up mappings that says all the pie files pass them to this servlet. And then to implement the actual servlet, it's as easy as creating a class with, well, we have do get here. So it's do post, do delete, so on, which gets request and response objects and you write output, you set headers, just like you would in Java land, what you do in Python. So this is all that needs to be done. Those two files are working Python code in, yeah, okay. So it doesn't change. So let's, this is part now. And if we reload the page, this is part now. This is a bit faster than deploying to enterprise Java applications normally, especially if you go beyond Tomcat. And the other thing is that's worth noting here. I won't go into more detail here because this is so simple that it's not needed. It's that if we do something, yeah. Oh, sorry. Sorry, of course. Sorry. Sorry. Sorry. I thought so. I don't, I have crashed my, actually, I think I just broke Sublime, should have used some other. Let's see. No, it doesn't work. Okay. So I can't for some reason. But what I wanted to show was there is no error function. I can't hear what you're saying. Sorry. I don't actually have the time. Sorry. But I introduced a syntax error into the code. And what I wanted to show you is that even if it's in the Python code where syntax errors, we get perfectly understandable stack traces. GIFON is actually really good at that. You do get the Java stack trace, which is this part. But on top of it, you have the same Python error message when you do, when you have syntax errors or any other runtime errors. And this is really convenient because not all FFI calls gives you this much information. So I will not talk more about servlets because they're so easy. However, embedding GIFON is a more general case. You want to do something complicated in Java, which is simple in Python. For me, this has been mainly operating system integration. Because to do the same things, you can go to the box with the Python standard library. We'll often have you download lots and lots of files or in third party libraries to do conveniently in Java. You can also embed GIFON to be able to do rapid prototyping, which is one of the first things I ever did with GIFON. And it's a bit more complicated than doing it the other way around. Calling Java from GIFON is as natural as writing Python. But calling Python from Java, if you do read the tutorials, they show you some really simple ways of doing it, which you will then have to replace. So this would be your typical FFI wrapping code where you need to actually take care of getting the types right from Java. So what you can see here is that we create a module to wrap the Python code when we instantiate it or a class, rather. When we instantiate it, we create a new Python interpreter. We execute the imports in it to pull the Python code into that interpreter and then we get a pointer to the py function so that we can call it. And as you can see that when we do call it, we use the dunder call because any py object can be called. We could have used invoke, I suppose, instead here, but this would be the general case. And we need to tell them what types we send and we need to tell them what types we want to return, of course, because this is Java land. And, of course, we need overloading and so on if we want to handle different types. And if we compile this file and then run it, it gives you the square of 2 and 2.2. So the Python part of this has no Java specifics at all, actually. So run it. But everybody does this example, more or less, when they do FFI, demonstrate FFI, PyC types, for example, has this called time thing because that's easy. It gets complicated when you're trying to do some stuff with arrays and custom data types and so on. And that's also the case with Jython. So the first thing I ever did in Jython was this, a bit more complicated with path optimizations prototyping. And calling, throwing the arrays into Python, really simple. Getting the results out in a convenient way is trickier. As you can see here, I don't get an array back. I get an iterator over high objects, which I then need to individually cast or maybe wrap in something else to make it easily accessible from a proper Java perspective. So normally you would want to use some kind of callback so that you actually push data from Jython into Java instead of trying to return complex values. I'll show you one way of doing this when we talk about scripting. Adding scripting to Java is possibly easier than straight up embedding. And it's a really convenient way to add scripting because Jython is so easy to integrate. So if we want to allow a user or administrator or whoever who is not doing our Java coding the ability to make a choice in this case, we can allow them to supply a Python code. This could as easily just be a source file or sent over the wire or whatever. Give me the script file. And again, we import it. Of course, if we had the source file in another way, we could just tell it to execute all of this entire string, which could be all of our Python code. And then we can call it. And this is one way of doing the, that I'm showing here, is that instead of trying to get a return value from the Jython call because the call to Jython will always return a py object, which can be anything. And the ways of casting that into the proper type is either complex or expensive. So what we do instead is that we let the Python side know about where to put the answer. So we actually do a call to get the answer. And then we return with this scripting decision, which is just a static in this case to make the example even simpler. And the Python code imports the scripting class and makes the choice and puts the answer there. So using a callback pattern not to achieve asynchronous behavior, but to use the fact that it's easier to call into Java from Jython than the other way around. So if we run this, it works. So you can add anything in there and it will work. And the last way I'll talk about using Jython is using Jython as a test bed. And this is the way we use Jython today a lot. Some code is really hard to test well. And some things become really verbose when writing them in Java. So for our specific perspective, we have Java micro addition code running on several different versions of hardware. And we need to test this code or rather we need to test the application for resilience and fault tolerance. And sure we have unit tests, but they tell us the obvious things. This function doesn't work the way we intended it to. It doesn't tell us what will happen if the DSM network starts to report out of bounds values. And first we were trying to kind of extend our unit tests into some kind of functional test things in Java. But we ended up with so much code that we got this, I suppose anyone who's been in the industry long enough have seen when you have the test cases are actually freezing the design because you have so many tests and so much mocking that if you change anything, the tests break even though nothing really broke. So we decided to do it in another way. We have in Java land this device handler which basically lies right on top of the metal and lets us ignore that we have different firmware versions and slightly different hardware and so on. So we create a, in Python, we create a class factory which create classes derived from this device handler and we supply it with some same defaults. And then we supply it with some default implementations of calls to the hardware layer. So if you call beep, it will print beep to the console instead, for example. And this way we have a hardware mock which lets the application run and not do anything useful. It stores data, it records, I haven't shown any here, but some calls are recorded so we can introspect this device handler object in the end. And we also added these small snippets so that we can, for every test, we can get a new class specified for that test and replace some of the methods that we're interested in for that test. So the way we use this is that this is a real test that we have. We need to test that the auto-update. This is one of the very simplest tests we have. That if the auto-update succeeds and it gets a version number that's higher than the current version number, it should trigger an update. So what we do is this get to be a HTTP connection is a way to get a string from a string contents of a URL which is used throughout the application. So for this specific version we just say return crap if we don't recognize the URL because the application should keep on running anyway. But if anyone is asking for the required version from the REST API, then always return 999.99. So we use our factory to create a new device handler with this newly created replacement function or method, really. Then we set the update rate to twice a second just to make it fast. And we run the entire application which means the application boots, runs self-tests and runs for three seconds and then shuts down. And then we use the, then we just check the device handler object that that method had been called that we were expecting. And of course this is a very simple example. We do the same with instead, okay what happens if we run the application and then the connection to the server hangs and when we're trying to run the, to reboot the GSM modem, it returns out of bounds values. Because that's an error case we had once and trying to test that without actually being able to run the entire code and do introspection on it is really hard. And on the matter of finding weird behaviors and bugs, the mock data handlers we create or device handlers we create together with the repo allows us to explore the behaviors of our application as it is running. Because we can basically just start the application. This application object is a Java micro edition midlet. That's what's running here. So it's a multi-threaded application, it has checks several, it has actually so many simple behaviors that it's a really complex application. And we can just start it and add the command line, start to okay, give in the SMS, break this, replace that and see what happens. So that when we have really weird logs of things that shouldn't be able to happen, we can start by trying to explore the behavior of our application in runtime and see how can we trigger these faulty behaviors. And this is extremely valuable when you have a domain where you don't really control, I mean we control everything right down until the network starts. And then we control nothing. And the J2ME application, the J2ME runtimes are buggy. And the GSM specification isn't as good as you'd think. So different GSM networks behave differently. And this gives us the ability to see, since we can't control that, we have to be able to make sure that our application can handle basically anything gracefully and not just die or something. So this is, of course also gives, since we do this in Python, it's really easy to add some fast testing. We just send random data as response to queries and so on. Just to see what happens to our application when things don't behave the way it should. And last, a little bit short. I've seen good and bad examples of using Jython. The thing is that adding a new language is not free. And when people want to add, they've just found Python, let's add Python to our stack. And you have this huge Java enterprise stack. It's really easy to just slip in another jar because, let's face it, there's already 200 jars in there so that works fine. The problem is that when you do that, as soon as anything breaks, it will be Python's fault and everybody will hate Python and you forever. So the thing is that I've actually tried to use this as an argument. It worked so, so. It's more fun than writing all of these things in Java. So that didn't really work. And that was the fact where we had OS integration and we said basically we need to download like 15 packages or we can add the Jython jar and have it just one extra dependency. The problem is that Java architects are really used to having lots and lots of dependencies so they're beyond caring. Just download Maven central everything and make it work. So there's actually only one single argument that has been working for me in corporate environments. I can do this in half a day or I can give it to you in a month or so. So this is the golden thing that, but it also means that you need to actually first know how to integrate Jython because otherwise you'll spend five days doing the integration. But as I have shown, I hope it's really easy to get started. And once you have the wrapping, you can really, really supercharge your Java stack development time. And of course, sometimes you have performance issues or some other aspects, but for general prototyping and testing especially, I think it's, there are very many gains to be had from this. And I am out of time. So I don't know if we have time for questions, maybe one or two. Yeah, that's four minutes for questions. Hey, thanks for the talk. So I'm really fan of the JVM and I'm a fan of Python. And it's a little bit sad that Jython lags behind in many places. So my first question would be what's, you showed many things, for example, the surflets and so on, the surflets, for example, which are dynamic. What's the benefit of using Python over the JVM languages like Ruby, Scala, Clojure? They're also... Yeah, I would say that I would use Python instead of Scala because I know Python a lot better. I wouldn't say that it's inherently better than any of the other alternative languages on the JVM. And in some cases, like Clojure, especially, I'd say that for some cases it's definitely worse. On the other hand, it's easier to get a whole Java program than a list programmer. Basically. I would... I've used some other languages on the JVM as well. And I would normally say that that's a choice depending on the competence of the teams or the organization you're working in, more than the technical merits of the language, actually. I just have a second one. Did you run a purely Python program with Jython anywhere like... Sorry. Did you run a pure Python program with Jython anywhere like in production or for test tooling or something? So what I mean is having the power of JVM but for just having the power for... I have used it to run a threaded concurrency because it's faster on the JVM that it is in CPython. Which one? Sorry. When you do CPU intensive multi-threading, the JVM is actually a lot faster because you can sidestep the JIL issues entirely. But that's the only case. I've actually done pure Python programming in Jython. Otherwise, it's always been an issue of integration with something existing on the JVM already. Yeah. I tried, for example, to do exactly this. So I had a small Jerry Py Hello World app and just benchmarked it with Jython and CPython and it performed worse than Jython even though it has a whisk concurrency, of course. So it was a little bit disappointing to see Jython perform so bad. Yeah. I mean, there is a performance impact, of course. So I think that the only times that you actually can say that it will be faster is that if the JIL is actually your problem, which it's mostly not, then this is one solution to that. But I don't think you should expect better performance. So yeah, we've run out of time now. So thanks again to Frederick for the talk. I'll be back in a minute.