Issues with classpath running Jetty via Maven - maven

I'm using Maven to manage my build. For developer testing I use Jetty which I launch using the jetty:run goal in the Jetty Maven plugin. I should also note that I have war:exploded running in an earlier phase which builds the directory that Jetty runs against.
The problem I'm having is that the war:exploded task puts the build dependencies into WEB-INF/lib (as it should) and furthermore, Maven appears to be feeding Jetty the build classpath via the system classloader. This leads to every jar getting loaded twice which should be OK except that, sadly, the Datanucleus library throw an exception the second time it gets loaded onto the classpath.
The only solution I can think of at the moment is to create two profiles, a build profile and a developer test profile. The developer test profile would exclude all the dependencies and jetty:run would run in the developer test profile. This seems like a lot of configuration for something I think would be simple.
Does anyone know if there is a way to prevent Maven from loading the build classpath into Jetty?

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<useTestClasspath>true</useTestClasspath>
...
The option "useTestClasspath" should have the effect you are looking for.

Related

How does maven jetty package a war?

I am running an open source piece of software (https://github.com/att/XACML) and the documentation says to use maven jetty to run the application. This works fine.
However, I am trying to run it without maven as a dependency, so I am thinking of using the generated war and deploying it with jetty. However, this approach gives me errors specific to the war (can not instantiate null etc.) that do not sure up when running maven jetty.
So my question is: how does maven jetty package the war? Is there anything it does at runtime that would make it different than just trying to deploy the war on its own? What is the difference between using maven jetty and using something like jetty runner with the war generated from maven clean install?
Jetty does not package a war.
Maven does, and you need ...
Your project's pom.xml should be declared as <packaging>war</packaging>
You have a src/main/webapp directory.
You have maven execute the package phase.
When you use something like mvn jetty:run-war the first thing that happens is the package phase executes, THEN the jetty:run-war goal executes.
See: JettyRunWarMojo.java
#Mojo(name = "run-war",
requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
#Execute(phase = LifecyclePhase.PACKAGE)
public class JettyRunWarMojo extends AbstractMojo
Jetty is not doing the packaging of war, Maven and it's default package phase is (and the behaviors here are determined by the standard maven lifecycle defined by your <packaging>war</packaging>)
See: https://maven.apache.org/ref/3.2.2/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging

How to specify JDK in maven jetty plugin

How to specify JDK in maven jetty plugin?
Like this:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
<configuration>
<scanIntervalSeconds>2</scanIntervalSeconds>
<webApp>
<contextPath>/${project.build.finalName}</contextPath>
<jettyEnvXml>${project.basedir}/src/over/here/jetty-env.xml</jettyEnvXml>
</webApp>
<httpConnector>
<port>8080</port>
</httpConnector>
<!--<executable>${env.JAVA_IBM_HOME}/bin/javac</executable>-->
</configuration>
</plugin>
Please note: the excutable tag is incorrect, I just use it as an example.
To clarify: you actually want to specify an executable, so probably an JRE (Java Runtime Environment) and not a JDK (Java Development Kit). While it is true that JDK serve as JRE as well, this is a required clarification in my opinion.
Coming to your question, there is no such a think to specify a different JDK/JRE used to execute a certain Maven plugin: plugins are executed as part of the mvn command, which in turn is executed using the system JDK/JRE by default (set in the path) and it is actually a script which invokes a plain Java main, yes, Maven it's written in Java and its execution starts from a Java main, the following one to be clear:
org.codehaus.plexus.classworlds.launcher.Launcher#main
If you want to change the JRE used to launch this main, you need to change the JAVA_HOME variable upfront, as also explained by this old SO post.
So you would need the following:
set JAVA_HOME=path_to_your_different_jdk
mvn jetty:run
In your IDE and according to the screenshot you posted in your answer, you are actually doing the same: setting which JVM must be used.
This is true for most of the plugins, unless a specific forking mechanism is foreseen. For instance:
The Maven Surefire Plugin provides a fork mechanism via the reuseForks option and the jvm option, which also explains that:
Option to specify the jvm (or path to the java executable) to use with the forking options. For the default, the jvm will be a new instance of the same VM as the one used to run Maven.
The specified JVM (JRE or JDK used as JRE) will then be used to executed the tests (basically the same scenario you were looking for concerning the Jetty Maven Plugin.
The Maven Compiler Plugin also provides a fork option which can then use an executable option where you can effectively point at a different JDK (and not JRE in this case) to compile your code.
Sets the executable of the compiler to use when fork is true.
The Jetty Maven Plugin is executed as part of the Maven command (again, a Java main using the JRE specified by the JAVA_HOME variable or the default of your system), as also specified in its official documentation:
The classpath of the running Jetty and its deployed webapp are managed by Maven
...
For example, you might need to run your webapp in a forked instance of Jetty, rather than within the process running Maven;
And indeed a run-forked goal is provided
This goal allows you to start the webapp in a new JVM, optionally passing arguments to that new JVM. This goal supports the same configuration parameters as the jetty:run goal with a couple of extras to help configure the forked process.
This option however is mostly used to pass different arguments to Jetty rather than a different executable (for example, in case you already set the same argument for Maven and you want it with a different value for the Jetty run). So, again, the option is not there (to specify which executable/jvm to use for this forked execution). That's a pity, because they got almost there with this goal.
I think I got the answer by myself, but I still don't know how to do it in maven xml file, if you know it, please tell me.

How to pass '--list-config' to Jetty when using maven jetty plugin?

We can pass arguments like '--list-config', '--list-classpath', etc. when using Jetty's start.jar as shown at http://www.eclipse.org/jetty/documentation/9.2.8.v20150217/startup-classpath.html and http://www.eclipse.org/jetty/documentation/current/startup.html
I was wondering how could I pass them on while using Jetty Maven plugin. I tried < jvmArgs > and run-forked but that didn't work.
jetty-maven-plugin is just an embedded-jetty for Maven plugins.
It is unrelated to the jetty-distribution's start.jar standalone operation.
For the jetty-maven-plugin there is no Server Classpath, just the maven plugin's own Classpath, determined by maven, gleaned from the effective pom (pom hierarchy) of your maven build. Use maven's --debug to see the plugin classpath during the execution of that plugin's phase (note: the classpath can change between different phases)
The configuration is also part of the phase that the jetty-maven-plugin executes with. Again, use the --debug from maven to see that configuration.
The configuration you see from start.jar --list-config is 100% in the scope of the start.jar determination from the configuration information starting at ${jetty.base}/start.ini, and the selected jetty modules, along with your properties to build up a Jetty instance, a "pre-start" configuration that start.jar will execute to build up a Jetty instance.
Its like you are asking how to understand a bicycle (jetty-maven-plugin) by looking at an technical specifications manual for motorcycle (start.jar). There is only inconsequential overlap between the two: 2 wheels of approximately the same size, with handlebars, and a seat.
Yes, the differences between jetty-maven-plugin and start.jar configuration and startup are that vast.

What is the purpose of tomcat-maven-plugin?

I'm having some difficulty understanding the purpose of this plugin. Is it to modify the settings in Tomcat during the build?
I am deploying to tomcat using maven, without the plugin and it seems to work fine. Not sure if I am missing something
Cheers
Maven Tomcat plugin basically just bootstraps an embedded Tomcat container for you. Saves you the trouble of configuring an external Tomcat instance for development purposes. It can also auto-start this Tomcat instance during the build and run integration tests on it, stopping it afterwards.
If you already have a functioning workflow that you're comfortable with, no need to introduce the plugin, but it's pretty easy to configure, can run multiple web apps, can run unassembled applications etc so it's convenient to have for local development.
An even more light-weight alternative would be the Jetty plugin which starts an embedded Jetty server instead.
Maven is actually a plugin execution framework where every task is actually done by plugins.
Maven Plugins are generally used to :
create jar file
create war file
compile code files
unit testing of code
create project documentation
create project reports
A plugin generally provides a set of goals and which can be executed using following syntax:
mvn [plugin-name]:[goal-name]
For example, a Java project can be compiled with the maven-compiler-plugin's compile-goal by running following command
mvn compiler:compile
for more information go to http://www.tutorialspoint.com/maven/maven_plugins.htm
so pulgins is used to execute goals.
suppose if you don't include plugin that is required in your execution environment then it will throw an error like
A required class is missing: Lorg/apache/maven/plugin/BuildPluginManager;
so by adding appropriate plugin in pom.xml it will resolve the dependencies and execute the goal succesfully.
to remove above error just add the following plugins :
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-amps-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
</plugin>
Maven is a framework used to build JAVA applications, it provides the following
Directory Structure
Configuration Files
Build Settings
It helps in easy and structured development, primarily used for REST API Calls.
Applications built on Maven Framework, would require the same to be deployed
Its better that you get the plugin installed, since on a long run you never know what dependency may go missing
-If this helps, Mark as Answer

Maven jetty or tomcat plugin with hot deploy option including dependencies

I have a maven project with root module called "sample" and two child modules in their own directories "sample-services" and "sample-web". "sample-web" is a war module which depends on "sample-services"
I want to be able to run my server from maven (it could be jetty, tomcat, or any lightweight server) and debug my code without using eclipse or intellij idea j2ee integration (for example in Intellij Idea community edition or other IDE that supports remote debugger) and just by adding a remote debugger.
I could start my app with "jetty:run" and attach the debugger but the problem is that when I change my code in "sample-services" it doesn't pick it up unless I run "mvn install" on that module separately and restart the server.
Is there a better way to be able to debug the app and have the server redeploy the code changes without having to restart the server?
I know eclipse can do this for a maven project. It will detect the changes in dependent project and upload them to the server.
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.0.3.v20130506</version>
</plugin>
EDIT:
I ended up using tomcat maven plugin for now:
org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
/
true
in your pom.xml and run in the command line: mvn tomcat7:run
Downside is that this will reload the whole app upon each change instead of hot-deploy.
So now I am looking for a hot deploy alternative.

Resources