Unlike spring-boot,
JakartaEE applications usually organizes application code
apart from server code.
Java web projects used to be packaged into war
or ear
files and the server was managed separately.
I am trying to find a project layout for JakartaEE projects that comply with separation but behaves more like a
springboot app and, in order to get it, i am exploring the embedded app servers approach.
So far, i am thinking on a multiproject layout, one with regular JEE style structure and another with an embedded app
server consuming the first one. Gradle and maven both supports it:
https://docs.gradle.org/current/userguide/multi_project_builds.html
https://books.sonatype.com/mvnex-book/reference/multimodule-sect-simple-parent.html
For the embedded app server i found these samples so far:
https://blog.payara.fish/what-is-payara-embedded?
https://www.ibm.com/docs/en/was-liberty/zos?topic=liberty-embedding-server-in-your-applications
Simple Embedded Tomcat 10 Example
https://github.com/wildfly/wildfly-core/blob/main/embedded/src/test/java/org/wildfly/core/embedded/EmbeddedServerFactorySetupUnitTestCase.java
https://www.eclipse.org/jetty/documentation/jetty-11/programming-guide/index.html#creating-helloworld-class
A good article on this topic follows:
https://www.baeldung.com/executable-jar-with-maven
For the project layout i don't have much ideas yet, i am only sure about the
separation of the two modules. A few questions so far:
should the embedded final jar file be an uber jar?
should the war/ear artifact be repackaged?
why this approach isn't more popular, given the clear success of sprin boot?
Related
I'm working on a set of independent applications that share some common endpoints. The way I have it setup is to have each application be an independent war, and to have an embedded jetty server which provides those common endpoints. The embedded jetty server sets up the endpoints and loads the wars upon start. Each of our customers will have different applications installed, but will always have the common part, hence the need to have independently installable application wars.
This basic architecture is working ok, but in the development cycle I need to build each of the applications war to then run the whole thing with the embedded jetty server. I would like for the whole thing just to auto deploy when changes are made to any of the application files.
Any thoughts on how to do this?
Use a DeploymentManager with a WebAppProvider to find the webapps and deploy them (it will auto-redeploy on change).
Then setup your deployment to use exploded webapp directories, not war files.
You can even opt to setup deployment XML's in a single place, pointing to the contents of each webapp project's target/${project.build.finalName} directory (if using maven).
This works for many things, but not ALL things.
If you change classes or libs then there's a category of issues around memory leaks, and pinned classloaders, that can result in your reloaded webapp not behaving as you expect.
See
https://www.eclipse.org/jetty/documentation/current/preventing-memory-leaks.html
I am working on a project using the Java Spring framework, but I am (even after googling or looking through tutorials) unable to understand how it should be used.
Situation:
The project is(or, will be) made up of 3 separate web applications(for three different uses/target audiences) that uses the same database and to some extent functions and/or classes.
Database/cryptography-related classes and such are in a common folder under the project root, which seems appropriate.
Then there is a folder for gradle, used for starting the program("./gradlew app-one:bootRun"), which I suppose makes sense.
Then, there is a folder for one of the web applications("app-one") with related source code(Controllers, Services, etc.) and whatnot.
Problem:
I am tasked with adding the second application. Is it suppose to be a separate folder in the root directory?(Logically/By framework standards)
If it is not, how do I know what belongs to which application?
Do I need to use separate gradle commands to start each of the three applications? Is that even possible, and is it recommended/efficient/the best way to structure everything?
If you want to use maven,you can create a multi-module maven project with parent pom having all dependency management.A core project(jar) having all core functionality and three web projects(war) for your web modules which depend on this core project.You can start build and run these projects with a bat script from one place only.
Our team is writing a server-client application where the frontend is an Angular.js single page application which uses a Spring MVC java backend. The backend serves the application files and the REST endpoints used by the browser end. We are using Maven as the main build system for the application.
We like to take advantage of require.js and r.js to minify the app at the end, and we are also using client side dependency management. Currently we are using bower to download Javascript libraries required but it doesn't feel right to me to download client dependencies to src/main/webapp since this is a source folder. However in order to avoid rebuilding the whole frontend module each time something changes in the client files, this seems the only sensible way to us. This way we can start a web server and it will automatically pick up changes without restart, but as i said this doesn't fit Maven's folder layout.
I'm experimenting with Webjars which seems a better choice in our Maven oriented build and dependency management. Because in Servlet 3.0 containers webjar resources are provided automatically on the server container path it's very easy to use and manage them. It's also possible to create a require.js config to refer to libraries contained in webjars since they are on the webserver path the same way if they were static files, the serving is being done transparently in the client applications point of view.
My only problem is that i don't know how could we achieve r.js minification with this layout, since the source files are in jar files r.js cannot access them. Also the require.js config refers to the runtime server paths which are simply not there in build time.
I see that webjars now have some integration with Require.js + Play Framework but we are not using Play just simple Spring MVC in our case. I really hope there is a way to handle this case because i like the Webjar way of client dependency handling.
You need an asset compiler / pipeline in your build process. There are probably many options but the one I know of is wro4j: http://alexo.github.io/wro4j/
I have a maven project which generate zip generated from ant scripts. Then this zip is deployed to specific application server again using ant script. this is very complex for maintenance. Now we move to use maven for building zip, so what is standard way to doing with respect to developer and client
How to handle application server specific deployment(e.g for weblogic and jboss) Do I need to create 2 zip for each server?
How to handle global configuration parameter like database, product specific settings. Where to put them, and how it use by developer and client?
The installation of application sever is need to integrate with build cycle or what is best practice for it?
I'll try to answer based on my experience:
I use maven profiles for this. Especially since there are beans (classes) that are specific to only one app server at a time. See http://maven.apache.org/guides/introduction/introduction-to-profiles.html
maven supports placeholders. One build for every single environment: dev/qa/prod,etc. All you need is the properties file. (this is similar to properties in ant)
You do not need (usually, unless you have integration tests that are tight to the app server - and if you do, it seems wrong) an app server for the build itself.
All -
we have several web applications, all based on some version of Spring developed over time by different team across organizations. They each produce their own WAR, have a different context to work within, and often gets deployed on the same machine, as their functionalities are closely knit together. So we end up with:
tomcat/webapps/{A, B, C ... }
upon deployment, each use a very similar set of tool chains, replicate all Spring jars and dependencies all around.
I am wondering if there is a way to make the project structure better, deploy as a SINGLE war, while allowing each webapp live in their own source repo and have its own pace of development??
Any pointer or references are much appreciated.
Oliver
Deploying in a single WAR will couple all the projects together. Modifying one will mean redeploying all, with the accompanying QA effort to validate and do regression. I wouldn't recommend that.
Multiple copies of Spring JARs can be addressed by putting them in the Tomcat /lib; they're loaded by the Tomcat class loader instead of the WAR class loader. That will mean that every app has to be on the same version of Spring; upgrading one means upgrading all. You'll have to regression test all at once.
What harm is separate WAR files doing you? What do you care if the Tomcat /webapps directory has lots of deployments? One advantage is that they CAN be on separate release schedules. That's a big one to give away. Be sure you have a good reason before doing it.
you would have to probably move to an app server like jboss, but couldn't you use an ear file and have maven build the modules for you? That way you could probably put them in separate repos if you want each with it's own pom and then have another project with a pom for the ear file:
here is the maven ear plugin:
http://maven.apache.org/plugins/maven-ear-plugin/
here is an older blog post about multiple spring app ear file (single applicationContext fo all wars to share if you need):
http://blog.springsource.com/2007/06/11/using-a-shared-parent-application-context-in-a-multi-war-spring-application/
Based on one of your comments to another response, it sounds like you might be more interested in maven's multi-module project feature. This will allow you to define a parent POM with consistent dependencies and project layouts managed across multiple projects.
You might benefit from combining each project into a single WAR, but I do think this is really one of those 'the grass is always greener' problems. One key thing I would keep in mind is figuring out how much longer (or shorter!) is redeployment going to take if the projects were combined.
Think about OSGi. You can deploy all the dependencies just once, build your separate but interrelated modules as OSGi bundles, and deploy and upgrade them all independently. You can also choose whether to deploy them all as WARs (web bundles) or to deploy them as JARs with one or many WARs importing them to tie everything up. Virgo Web Server, formerly Spring DM Server, is really nice and comes ready to do this kind of stuff right out of the box.