About this talk
In this talk, Sandra Pasic discusses the organization and maintenance of Apache Maven builds. As a freelancer and product lead in the Apache Maven community, she emphasizes the importance of a solid baseline for Maven projects and shares practical tips to avoid common pitfalls such as outdated configurations and dependency management issues. Pasic explores tools like the Maven Enforcer Plugin and Maven Dependency Plugin to manage dependencies effectively and automate maintenance tasks. She also highlights the significance of using build profiling and remote debugging techniques to enhance performance and troubleshoot issues. Throughout the session, she underlines the value of having a deterministic approach to software development, especially when working in an open source ecosystem.
Full transcript
Yeah, welcome everybody. Nice to see you. I know um it was a big challenge to to choice lunch on my talk. So, I will be great that you're here. So, welcome to my talk painless organization and maintenance of a Apache Maven builds. So, I hope we everybody knows what Maven is because this is not the beginner talk about Maven. It's got more So, I will skip the
introduction to Maven. When there are some Gradle fans here, I don't want to one here. So, I know in Gradle there maybe some smoother, but I know there are other stuff that not so well works so smooth. So, yeah, let's have a chat about it later on. So, yeah. Um the organization asked me to give the QR code for the for the questions. I don't know if
I took the right link to it. So, we will see later on it. So, yeah. Time to to registration. So, but some words about me. I'm Sandra Pasic. I'm a freelancer developer and consulting. And currently I I also the product lead support and care for Apache Maven. This is not the project at Apache Maven. It's a another working group that try to improve the fundings money some
maintenance work at Apache Maven. My main work topics are developing Java application mainly on the back end side. I'm not a front end developer. But also I like open source and community stuff and automation things on the deterministic way. I give training workshop and so on. And this week is very special for me because I have also a podcast that's in German, but we published the 100
episode this week. So, yeah. Thank you. So, maybe there are some listener of my podcast in this audience. I have some special tickers stickers because of the 100 episode. So, um you will maybe ask you what the heck is the project care. And supporter care is a group of projects in the Java base ecosystem. And we want to secure open financial stuff for this Java base components
like Apache Commons, Apache Maven. I mean, uh I think 80% of all Java project use Maven. Log4j, JUnit also, and the Eclipse Temurin. why we started it, we know maintenance is not fun. When you look at your daily work, when someone say, "Hey, we have to make maintenance work." everybody say, "Yeah." And especially in your spare time, you want to not deal with it, but also in
open source project, we need some maintenance work. And there are what we jump in. How it works, we have we collect the money from fundings from the actually from the German government. So, we can make some maintenance work like uh migration from Jira issues to GitHub issues. This was me and some other guys like Matthias. there was some fun with emails. And also we try to introduce
companies to give to make a subscription that we can use the fees to also support maintenance work in this um um open source project. And I know, we are in the capitalism way, so a company wants some benefit of them when they give some money away. So, one of them are you have connecting to the maintainer of this project. Um you can can get some consulting of
this maintainers. And also, you ensure that this open source project will be long um be long more. And I promise this is the last promotion slide. I also open source person. And we organize Java Unconference in Netherlands, the J-Fall. And yeah, the registration is open. So, if you want to talk about Java and go sailing or try to sail, that's your possibility to do it. So, as
I say, I promised the last promotion So, let's go to agenda. I have four topics for you. One I want to describe how I get a good baseline for my Maven project, how I can avoid problems to um that can come up during the build time, but with the pre-check, it will this is avoidable. And I know the favorite topic of every project, dependencies. Who loves dependencies?
Yes, me too. So, I invest some time to make my life easier. And I will introduce some tricks what I use to debug some Maven builds, but sometimes you have you have to go deeper and there are some tricks what we how we can handle it. Let's uh let's start with uh how to get a good baseline. And what I see in my project, the common pattern
is copy paste existing project and and start with this copy paste a new And fun fact, when you're using AI, it's the same. Copy paste on steroid. So, the same problem what we have in the AI world. why I think this problem can be uh this approach can be a problem. I mean, um, maybe you will copy uh, outdated uh, configuration. Maybe you uh, full of plugins
with outdated versions. Maybe you copy a configuration that's not match to your new project. Um, uh, so you have maybe plugins that are not useful for your project, but they're in because you copy-pasted. And um, yeah, when the old project has already some maintenance problem, you will also copy this problems. my for me the solution is we need a good baseline and based on a deterministic approach.
So, to make some generation that it's uh, based on statistic it's from for me not deterministic. And when I look at the uh, around, we have some approach like web-based approach uh, and some CLI approach. I want to show you okay, um, how they looks like. One of them is uh, an inside of for Apache Maven. It's a website that we created from this what I don't
care team. And um, when it's it's a good for plain Java project. So, when if you want to start a Java project with Maven that has no frameworks like Spring or uh, Quarkus, then this will be good uh, good approach. So, I don't Yeah. No. Uh, sorry there, not working, but uh, So, at the end, so uh, you will get a project structure that's um, has some
uh, some configuration that you need can start with the project like uh, pom.xml when you say I want to have a Maven wrapper, I can uh, the this approach can put a Maven wrapper on it and some sample code for for for the Java stuff. And when we look at the the generated POM that we have some um some details that are automatic setting. Of course, there
are some are opinionated, but some are follow good practices. Good practice for for something like um we set um the compiler release properties that we want to have a Java 25 then to have a source encoding is very important, so we set for you. But other stuff, there are some um opinionated like, "Okay, we choose uh as a default test framework JUnit." Because we as I see
my project, the most project want to use JUnit as a testing framework, so we say, "Okay, why not choose it as a default?" And other good practices are that we um pin the version of the of the plugins, so that you have the possibilities to uh get a more reusable builds. Why is important? When you don't pin this plugins in your build then and you updated the
Maven um distribution then it might be the version will also um updated, but you don't see it, so it's a good approach to make a uh to pin the version of that. When you are um started a project that's uh based on a framework, then it's be better to go to other in this like from Spring one. So, if you started a Spring the um uh project,
then you have a Spring uh site where you can um put your coordination you can select some dependencies and the uh website will be generate um project for you to um uh that you can start with the Maven uh with the based on Maven. But uh some of us um like to have a CLI approach, and one of the first possibilities to do it was Maven archetype.
So, it's a Maven plugin that you can call it and give some coordinates for for a template, like here the the the simple archetype. And then this plugin will generate a project for you. And when you look at the ecosystem, there are many templates available. So, for every kind of project, you can choose the archetype. but this is the also a disadvantage. There are so many, and
there are very big difference about quality and maintenance status. So, sometimes they are 20 years old, you will not use it. Some they are newer, it's okay. So, this is for my point of view one of the disadvantage of that. But the other side, um sometimes you it's good to have a look on it because when you're in an enterprise context, sometimes you have a special project
setup, and then the archetype could be a good possibilities to uh create a template in your company and spread in your company to say, "Hey, please uh start it uh a new project with this uh this archetype." Of course, you have maintenance this template, but yeah, every solution has uh pro and cons. And another thing why this is also in many dev tools, my Maven archetype are
integrated, like here in IntelliJ. So, when you started a new Maven project in your IntelliJ, Eclipse, or NetBeans, then um and you have a possibilities to choose the archetype, and your IDE will also generate the project for you. If you want to learn about more IntelliJ feature for Apache Maven, uh please check Marit's and Andres uh talk about getting more about out of Maven. They saw it
in them talk their talk. They show some IntelliJ feature how to work with Maven in IntelliJ. Another tool that is very new, I call it new kids on the block. Uh, it's the Mavenize uh toolbox. It's a mix of CLI and Maven plugin because you can in also use it as a main plugin, but you can also use it as a normally CLI tool. And there are
many commands and goals that uh possible to to make some maintenance work uh for your for your Maven project. And in this context um goals like uh create a new project, create a new subproject. In this case, subproject is um for Maven 3, it's the same like um um module, but uh the maintainer of this tooling uh started to use the new term of Maven 4. So,
it's called new subproject on that. and you can add uh plugins to run from the command line. So, I hope my uh yes, it works. So, you can um um or not. It's not working, sorry. So, it's possible to um to um add the command like here new project. You will um uh add the the coordinates. Then we can check the pom. Then we see, oh, it's
a plain pom with only my coordinates. So, it's not uh working anymore or not good. Then I can say, "Hey, please lock my plugins." So, he will um lock the plugin version. Uh, so I can follow the the good practices on that. And um then I can say, "Hey, maybe I want to have um a dependency." In this case, uh I would um add the Junit BOM
I will check it again. Yes, he will add in the right place my my dependency. And here there I see that it's very in very early stages of this this command line. It's a BOM that's so I in the real case I will need some more information. So I have to do manual work on it on it that it make work. But uh Yeah, for me it's
a good starting point to create a new project and to reduce the work what I have to do. The next I'd like to introduce you is some tricks how to simplify maintenance of my Maven build and comments. when I look up that there are some possibilities like okay introduce POM formatting to um to make the POM readable for all of your teammates and to add some pre-check
that so I can avoid build runtime error at the beginning so I will not waste time of building to to see oh okay, that's this what is can be checked before my build is started. And why POM formatting is useful Yeah, it's avoid noise in a good diff. So because you know from programming language every developer has their own style. Of course, POM formatting the same. So
when you look at your project, do you do you think in your pro project everybody have the same POM style? Okay, there are some okay, so there maybe. But in many projects there there are some battles about how to configure my my palm. And so, I can um um I can introduce the sort palm uh Maven plugin, so I can uh ensure during the build that uh
uh special style is um used to the to the to the palm. So, I can say here, "Okay, uh please don't make a backup when you have to to sort it." Um I want to have a special palm file order. For for for example, properties should be come before dependencies. I have want to have a special dependencies sort order, like, "Okay, group IDs should be together, compilers
scope should should be together, and so on." And this one, when someone put something in this palm, and the sort plugin uh see it, then here I can say with the sort uh goal, "Hey, please make it uh right formatting it like I like the by the definition." Or I can add a verify to say, "Hey, verify me if the palm is configured or formatting for for
like I describe." So, in this case, I can avoid uh some good diffs and noises uh in my in my The next uh thing is um that I want to have uh some pre-checks before Maven start to compile or test my project. And the positive problems are like um "Oh, do you have set the right Java Java version? Do you use the right Maven version?" And so
on. And uh one of them what that can um so solve this problem is the Maven Enforcer plugin, and um it it's uh bind to the very first phases of the Maven build in an initial phase. So, I can say, "Hey, um please enforce um some rules." And I can give in my configuration the rules. And then the plugin will be checked for me before Maven make
the the right stuff. So, one example what I have here is um to check the correct Java version. So, I say, "Hey, in my project the required Java version are 11 or 17 or 21." And when someone use the wrong version, then my plugin say before the build started, "Hey, you use using Java 8, but it's not in the range. So, I am he will stop it
in a half of a second." And in this case in um also maybe some relevant sometimes when you are using special Java vendors. For example, you has a SAP uh special feature for your FM. And um someone of the your colleagues want to use the Oracle one, then you can say, "Hey, please don't use Oracle JDK." uh enforce and checking the right right right FM vendor. And
it's the same with um operation system. Sometimes we have to a developer software that is special for a special operation system. So, I can this is you need a Windows machine or Linux machine to run this build." And this is this what I can um ensure with this this rules. Another problem what I see is to choose the right Maven version. Um and this I I think
this problem was the last year not so so big, but uh when you have this change between uh 2.6 and 3.8, then it was very important to use the right Maven version. So, you can add a rule that required a specific Maven version. Again here, the plugin will say before the build please use the right Maven version." And I know the Gradle fanboys here say, "Oh, that's
old. We have a better solution for that." Yes, I know. We, uh, copy it from from you can also, uh, use a Maven wrapper in your project. So, um, you can set up it with Maven wrapper and it will put some binaries or shell scripting in your project. So, when you running the wrapper, it will be ensured that the right Maven version is used in your, uh,
project. There are many operation models, uh, like, uh, "Hey, um, please add the binary in your GitHub repository or download it if you don't find it on the machine." It depends on your working area what's, uh, the best approach are The next topic, uh, that I want to to introduce you is in dependency maintenance. And, uh, I think it's that we have to look, uh, how dependency
management looks like in Maven. I give a quick, uh, uh, um, overview of that. And then we will go deeper about dependency cleanups and how to stay updated in our day. the, uh, central point in Maven about dependencies are the, uh, dependencies, the dependencies element, and dependency management element. And, uh, when you look at the POM, uh, when you want to put, uh, a dependency, so you
can do it directly, group ID, artifact ID, version in this elements. Or you introduce a so-called the dependency management then here if you both do both thing but the good thing of the dependency management is that you uh delete or uh the version in the dependency part so you have only one one point to set the or one location to set the the version. And um this
is what effect of this. When you if you put effects um if you put dependencies in your pom then you define which dependency should should be put on your class path of your of your of your program. So you can uh choose three class paths as like compile test class path and run time or or execution class path and uh this is what you uh control with
um dependencies um element. And let's have a look what's the what's the what possibilities we have. I say we have three class paths as but it depends on which kind of scope you are using you put this dependency on different class paths. Like when you use the compile scope is a default one that means if you don't set the scope it always on compile then will be
be on the compile part class path on a test class path also in execution that means when you're running the or make a bundle of your software this dependency will also package because um it needed for for run time. But sometimes there are some uh dependency that needed for compile and testing like this provider scope but maybe you are has a Tomcat application and there are some
dependencies that you need for compilation but you know they are inside of Tomcat so you don't don't do put it on the bundle so you will use the scope. The same are with run time that means I needed for test and execution but not on compile time and for testing and there are special uh two important system import is later interesting when I becoming to build of
materials and system they are coming from the very early day of Maven or the software development. Sometimes we had some dependencies that was on on the on our file system and not in in the Maven repository and so we have to give the Maven the hint, "Hey, this is a dependency that you don't don't find in the Maven repository. You have to go on the file system
to find it them." But it's only for for um um historical reason we have. I think I don't see system like 15 years not in any palms anymore. on the other side we have the dependency management and without dependencies um declaration this has no effects on your on your on your project. So if you have only single module project you can discuss if this is really needful
for But if you have a multi-module project that it can be very helpful for maintenance that you have only one single location where you manage the version of your dependencies. the other point is with this dependency management you can reuse bombs and um um in your project. So let's have a look how this works in a multi module project. We have a multi-module project is something like
you have a so-called parent palm. It's uh uh in most cases in the root of the directory. And now in some project they have another approach but I like this approach to put the parent palm in the root. And then you have directories that call um with the um own palm that is the so-called module palm on that side. management I will put in a parent pom.
So, I has declaration of dependencies management. In this case, I want to use for all my sub modules commons lang three in a specific version. And in my module pom, I can say, "Hey, please use commons lang three." But I don't need to declare the version because it's coming from the parent pom because there's the dependency management. And so, I can say, "Okay, one location for the
version." I can be sure that when my developer follow this pattern, that the specific version is I using. Because of of course, I can put the version on the right side and then it will be override the information from the left side. yes, dependency management and poms and then you will ask you, "Boms, what is that? Why is Why what could be important for me to know
about it?" the original idea of bill of materials are coming from manufacturer area. tell you a story. My husband is a machine engineer. So, he make some construct some big machine. And it's very common to to to create after the construction a bill of material. And in the machine area, it would be looks like that. And what is the task of this bill of material? So, when
he is talking with the production line, he can give them this bill of material. So, the mechanical knows, "Ah, these parts I need for build this machine." And it's to find out and not to go to the big plan to find out which part I need. The same for the buying department. They have sometimes buy third party components to build a machine. So, they can use this
bill of material to find out, "Okay, when we have to produce this machine, then this kind of components we have to buy." Um and it's easier and um very easy to understand for everybody in the company what to do. And this uh this uh approach we can use in a software engineering, too. For example, when you using the test framework JUnit, they have many uh components. So,
you have JUnit Jupiter, Jupiter RP, Jupiter Engine, and so on. And you want to be ensured that when you use JUnit JUnit in a special version, that all components of this library will have the same version in the site. And how do find in in Apache Maven? You um create a project with the packaging POM, and you uh use dependency management to define, "Hey, this is my
bill of material. This this um artifacts um uh believe uh are part of my my library, and when someone use this bill of material, um he will use this um artifacts and define this version of this artifacts." So, when I want to you use it in my my uh project, I will put this BOM in my dependency management. I will say type BOM in a scope import.
And um here why we need the import. And during the runtime, Maven will look at the BOM and the content of this BOM, and it will include import this part in the effective BOM that it's um using um in the build. And when I want to use my the artifacts of this BOM, I can put it as I know in my dependency, and I know the version
will come from the from the bomb through through I can be ensured that I will using the right version that are compatible to each each other. But we are not in a perfect world. So sometimes you can have a library that have many components but publish a bomb. And the solution in this case is to use feature of Maven properties. And for example, I don't know if
someone use JGit. So then you know this problem that JGit has many artifacts that you have to introduce in your project but yeah, no to have good place to manage the And one of the possibilities is that you introduce a properties. It's like a variable that you put in on the in your pom. And then you can reference in the to this property. So Maven will know
the version of this dependency is in in the property and then we can reuse it. And now we have a war flame. What's the best approach? So some of some of developers say, "Hey, let's put everything in a dependency management and control the properties there." Others say, "Hey, we have this single source of truth properties. So why not to reuse it in every project?" So it depends
on how your project looks how how to deal with it. I like to use it dependency management when I have a multi-module project. So I the properties are um, using correctly. Of course, sometimes not, but uh, in common. And so, um, but you I'm fine with that but if you used another approach. The next problem, uh, what we have is, uh, how to find unused, uh, or
using transitive dependencies. It's very easy to find out that you missed a dependency because your compiler said to you to it to you. But, uh, when you have, uh, dependencies on your class, but they are not using, um, do you have not so many possibilities to find out. Or you make some brute force on it. So, uh, the we have a plugin that's called Maven dependency plugin,
and the dependency plugin is the one that can help you on the side. So, I have a goal dependency analysis only, and he give me, uh, report on it. Hey, uh, which dependency are used but not declared, it means they are coming from transitive side. Or I used, um, uh, I have, uh, dependency on my class, but they are not really using of it. So, I can,
um, have also a list of them, and maybe I put some dependencies on my class path, uh, on compile class class path, but, um, they are only using in, uh, in testing. And so, this report can help me. And I can introduce this report, uh, in my builds. So, in every time I running my build, he will check my dependencies. And when I have, uh, some warnings
on that, then I can say, "Hey, fail, please, my build uh, when your dependency are not correct." So, I force the developer to have a look on it and decide and, uh, to to decide what to do. And of course, not tooling is perfect. So, of course, like you know from SonarQube or someone or sometimes you have false positive um um result of it, that so you
have to dealing with it. And I uh put two problems. Uh the first problem is that I use the undeclared dependencies, and the second one is that uh I have some trouble with the Jupiter dependencies because of the one side they say I use the undeclared dependency, and the other side they say to me, "Hey, you use you unuse a declared dependency." let's have a look at
what's uh what's inside. The first problem is very easy. I have to What's happened here? commons-io is coming as transitive from the other and I use it because, you know, IntelliJ say to you, "Hey, you want this one? Import and go go ahead." And so, it's very easy to fix this problem. I will um explicit explicit explicitly declare my commons-io in my uh dependency management, put it
on uh my pom, and everything is fine. So, it's very good for my future me, then I can see, "Ah, I want to use this uh this important, and I have the version of which um version I using for commons-io on under my control and not from transitive." So, I will fix some future problems for me. The second problem is not so easier because um when I
look at my pom, I uh introduced the JUnit bomb, and I use this uh dependency JUnit Jupiter. And when I look at here, he say, "Okay, the JUnit Jupiter is unused." And this for me is like, "Okay, some question mark in my head." But he say, "About the using JUnit Jupiter API." So, what's happened? Then I can make some analyze like with Maven dependency tree, and I
can see that JUnit Jupiter API API is coming from JUnit Jupiter. So, it's a transitive um dependency, and I can ask me myself, "Okay, what's happened here?" Okay, the explanation of this effect is the JUnit team published a so-called aggregator dependency because they find out that many people very often use JUnit Jupiter API, JUnit Jupiter Params, and JUnit in the same time. They say, "Okay, why we
not put this in one library, and so we can save some typing time?" And but in this case, the tooling say, "Hey, you're using something what is not decorated." So, what is the solution? We have In my my opinion, we have two possibilities. Don't use aggregator Yeah, I know. Um not a good idea. I like the this aggregator dependency. Or I give my Maven dependency plugin some
information how to deal with that. give him some context and say, "Hey, please ignore org.junit.jupiter in your report because I know this is a false positive, and also um ignore them in unused declared dependencies." And this is a decision human make a decision. And because I know that's the In the In the future, I will always using JUnit in my project, so the possibility that I will
delete JUnit from my project is very low, and so it's okay for me that I say, "Please ignore them." And this is why I'm I'm fine with them to add it give this this ignore information to my dependency plugin. But of course I have more possibilities. um you have some uh project that um doing many reflection or very old versions of uh dealing with XML configuration of
Spring, then you have similar problems. Then you have to when you you want to use this feature, um you have to configure dependency uh uh plugin or how to handle this false positive. I know it's the same game what we sometimes play with SonarQube. Um and um for me the same level. And of course um the new kids on the block toolbox had also some goals in
this area that can help me to analyze some dependencies. So um say, "Hey, give me reports about my class paths, dependency tree, um project dependency tree, plugins what I'm using." So I so I have more more tools, more possibilities how to analyze my POM to deal with the with the with this issue. And so then what's the next problem what I very often say um see is
that um that we have transitive dependencies or I want to avoid that some dependencies are coming inside. One use case was you make many work to introduce JUnit 5 in your project, but some guys don't understand it and put JUnit 4 uh in the class path. So you want to have some checks that it's uh not possible anymore. Or you know that's uh when we have log
for for J uh that the specific version should should be not coming in your project from transitive. Also, you um you can avoid at them. And so um So and the enforcer plugin has tools for that that you can say, "Hey, please ban the that someone of your team can put on the on the on the palm. Or you can say ban transitive dependencies to ensure that
nothing coming from outside in your project. And when you put this the same rule, you can put this rule in your configuration. Here, please exclude JUnit. Then the Enforcer plugin will enforce these rules before Maven started and it gives you a hint, "Hey, I will not start because there are some missing configuration." And the same with the ban trans- transitive depen- dependencies. Um yeah, the same result
on that side. And the next question is how can I avoid unwanted dependencies? I have the possibilities in Maven to say, "Hey, I want this dependency, but look at the transitive tree and when you find this dependency of the exclusion, please um um delete this from from the from the class path. I don't want it in the state. So, this was how to deal with unused dependencies.
But it's still a thing today to be up-to-date with versions. And in here, we have also possibilities to make some some tricks. Uh the main way is the the version Maven plugin. So, I can give some reports and automated with the version Maven plugin um to to updated the version. In this case, maybe I need some configuration to have better handling of the dependency And I can
also use the version plugin to find out if I can update my plugins. And this is very useful because some plugins needs a special specific Maven version. So, I get a report of them, "Hey, um when you want this update, this plug-in, you have also update your Maven distribution. So, you give some more information how to handle it on our on our side. And of course, toolbox
had also some goals for that. So, yeah, so you don't need when you don't want to have a special new plug-in in your project, maybe the for so one shoot task could be a good here is also many manual work of them and we have a look can have a look on applications. There are many software like Renovate that can automated this dependency update for us in
the CI. So, we get some pull requests on my project. I can run my CI builds on that to find out if this this updates are corrected. I can automated more like when I have a trust on my testing on my test, then I can automated the merge of this dependencies and so on. And the nice thing is I get also report of of the dependency update,
what's happened here to have more information and more small audit what's happened in in this in this case. So, the last topic for for this talk is debugging Maven builds. It's like um sometimes many developers struggling with the log outputs that cannot find uh Sometimes I spend many build time and then I have to find out how where my build time is going. And sometimes I need
some remote debugging to go inside because in the IDEs, everything is working, but when I started my Maven build, it's crashed. my favorite flag is um, minus X. Um I also call it pimp my Maven look for because I get everything. So, every plugin give me debug information what's happened, which properties are set, uh, and this is a the very good, uh, first step to go go
inside to find out, "Hey, what's happened in my build when something go looking looking wrong?" So, um, yeah, sometimes it's very difficult to read, but with the time you will find out how to, um, reorganizing them and then you can see, "Okay, this plugin was bind to this phase. It has this configuration." Sometimes configuration coming from a, um, parent form and so on. So, it's a good
first The next one is that's, uh, I need to find out where my build time is going. And then I can, uh, add build time profiler. It's a Maven extension where I can where I can make some measurement of my builds. So, when you put this extension in your in project, you can a this module needs so many time in this phases. So, you can, um, have
a deeper look in the configuration why it's happened. Maybe, um, you generated some sources and, uh, by accident they are doing twice and so, yeah, and then you can see it in the build time, "Okay, to have a look at this." And then you have more um, more ideas where to to look in more inside. The last tip what I have for you is, um, Maven remote
debugging. Uh, in the Maven distribution you have a Maven debug command. It's, uh, working like no normal Maven command, but he also but he uh, and then he also open a remote port for debugging. So, you can put, uh, connected your, um, IDE like you know it from remote debugging to this build and you can see what's happened in your test or someone when the Maven is
is is running. So, for me sometimes it's cover my ass to find out uh what's happening wrong on the other side. So, thank you for for coming. When I have to summarize summarize this talk, uh I think the golden rule is know your Um it will will be um knowledge I think Yeah, I know everybody's doing AI and generating code, but at the end when something is
not working, you have to know what your tools are doing. And um so, I hope I can I could give you some insight of that. And for me some useful plugins is like the Maven starter or the tools the tool boxes are really nice. And there are Maven plugins that also can help you to maintenance your your work on that. So, if you want to more hear
about me and my Maven knowledge, uh there are also uh training. It's in German, but maybe we can uh uh discuss about English also. Some um um so, compound that. And um my colleague Lisa make a very nice cheat sheet of them of this talk. They are here uh in the in the you can take something at home. So, I have many um samples of that. So,
and enjoy the conference.
More from this event
See all 34 talks →
Java: 30 Years and Beyond | Ana Maria Mihalceanu (EN)
39:47
Scaling Data in a Sovereign AI Platform | Johann Strauss & Markus Kett (EN)
49:29
Code Is Cheap. Software Isn’t. | Markus Eisele (EN)
47:23
Building a Digital Product Passport with Java and Cardano | Fabian Bormann (EN)
46:54