How to deploy multi-module Spring Boot Maven project? - java

Assume I have a Spring Boot Project Structure like below:
Main-Module
|
| +- Module-A
| +- src
| +- java
| +- ApplicationA.java
| +- resources
| +- static
| +- css
| +- js
| +- templates
| +- index.html
| +- pom.xml
|
| +- Module-B
| +- src
| +- java
| +- ApplicationB.java
| +- resources
| +- static
| +- css
| +- js
| +- templates
| +- index.html
| +- pom.xml
|
| +- Module-C
| +- src
| +- java
| +- ApplicationC.java
| +- resources
| +- static
| +- css
| +- js
| +- templates
| +- index.html
| +- pom.xml
|
| +- pom.xml
ApplicationA.java, ApplicationB.java, ApplicationC.java run on different port separately, such like 8080, 8200, 8300.
Also, Module-B has dependency of Module-A.
May I ask how do I deploy this kind of multi-module project, each module has it's own "#SpringBootApplication"?
Will it be deployed into a single jar? After running the jar, all the "#SpringBootApplication" will be started?
I tried to execute maven package command, and I got 3 Jars (3 sub-modules).
Then I don't know how to deploy them, such like deploy to AWS.
Also, there are not much answers found related to this problem.

Perhaps you would need to deploy each applications seperately. You can deploy the applications individually or depending on how you want it.
There are multiple offering from AWS to deploy our java applications here are a few among them.
If you are looking for a solution with containerized approach : AWS Fargate
For a managed solution for running java apps using Tomcat Platform / Java SE Platform : Elastic Beanstalk
Additionally you may explore EC2, if you are looking to manage the instance by your own.
Here's a offical spring guide for deploying your spring boot application on AWS.

Related

java.util.ServiceConfigurationError: org.apache.juli.logging.Log: org.eclipse.jetty.apache.jsp.JuliLog not a subtype

I am trying to port over a project written over a decade ago to Java 11.
After a couple days and some progress, I'm stuck at this error:
Caused by:
java.util.ServiceConfigurationError: org.apache.juli.logging.Log: org.eclipse.jetty.apache.jsp.JuliLog not a subtype
at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:588)
at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1236)
...
If I jar -xf my uberjar and (rip)grep through it, I see both the JuliLog and juli.logging versions:
rg "JuliLog|juli\.logging"
jar/META-INF/services/org.apache.juli.logging.Log
1:org.eclipse.jetty.apache.jsp.JuliLog
jar/META-INF/maven/org.mortbay.jasper/apache-jsp/pom.xml
216: filter:="(osgi.serviceloader=org.apache.juli.logging.Log)";resolution:=optional;cardinality:=multiple,
235: org.apache.juli.logging;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}",
jar/META-INF/maven/org.eclipse.jetty/apache-jsp/pom.xml
28: <Provide-Capability>osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer,osgi.serviceloader;osgi.serviceloader=org.apache.juli.logging.Log</Provide-Capability>
45: <exclude>META-INF/services/org.apache.juli.logging.Log</exclude>
From that, I saw different groupIds for the same apache-jsp artifact, but it turns out one is a dependency of the other:
mvn dependency:tree | grep -i apache-jsp -C5
...
[INFO] +- org.eclipse.jetty:jetty-servlet:jar:9.4.31.v20200723:compile
[INFO] | \- org.eclipse.jetty:jetty-security:jar:9.4.31.v20200723:compile
[INFO] +- org.eclipse.jetty:jetty-webapp:jar:9.4.31.v20200723:compile
[INFO] +- org.eclipse.jetty:jetty-xml:jar:9.4.31.v20200723:compile
[INFO] | \- org.eclipse.jetty:jetty-util:jar:9.4.31.v20200723:compile
[INFO] +- org.eclipse.jetty:apache-jsp:jar:9.4.31.v20200723:compile
[INFO] | +- org.eclipse.jetty.toolchain:jetty-schemas:jar:3.1.2:compile
[INFO] | +- org.mortbay.jasper:apache-jsp:jar:8.5.54:compile
[INFO] | | +- org.mortbay.jasper:apache-el:jar:8.5.54:compile
...
In my pom, I only specify the eclipse apache-jsp, which I'm including to prevent an error relating to lack of JSP support (2020-09-15 10:08:50.037:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /my-application, did not find org.eclipse.jetty.jsp.JettyJspServlet)
The other questions on StackOverflow were relating to dependencies on tomcat (either explicitly or via Spring) or gwt. I have none of those, but I do have some dependencies on other jetty jars, if that matters:
mvn dependency:tree | grep -i tomcat -C5
# no results
mvn dependency:tree | grep -i gwt -C5
# no results
mvn dependency:tree | grep -i jetty -C5
...
[INFO] +- org.eclipse.jetty:jetty-server:jar:9.4.31.v20200723:compile
[INFO] | +- org.eclipse.jetty:jetty-http:jar:9.4.31.v20200723:compile
[INFO] | \- org.eclipse.jetty:jetty-io:jar:9.4.31.v20200723:compile
[INFO] +- org.eclipse.jetty:jetty-servlet:jar:9.4.31.v20200723:compile
[INFO] | \- org.eclipse.jetty:jetty-security:jar:9.4.31.v20200723:compile
[INFO] +- org.eclipse.jetty:jetty-webapp:jar:9.4.31.v20200723:compile
[INFO] +- org.eclipse.jetty:jetty-xml:jar:9.4.31.v20200723:compile
[INFO] | \- org.eclipse.jetty:jetty-util:jar:9.4.31.v20200723:compile
[INFO] +- org.eclipse.jetty:apache-jsp:jar:9.4.31.v20200723:compile
[INFO] | +- org.eclipse.jetty.toolchain:jetty-schemas:jar:3.1.2:compile
[INFO] | +- org.mortbay.jasper:apache-jsp:jar:8.5.54:compile
[INFO] | | +- org.mortbay.jasper:apache-el:jar:8.5.54:compile
[INFO] | | \- org.eclipse.jdt:ecj:jar:3.19.0:compile
[INFO] | \- org.eclipse.jetty:jetty-annotations:jar:9.4.31.v20200723:compile
[INFO] | +- org.eclipse.jetty:jetty-plus:jar:9.4.31.v20200723:compile
[INFO] | | \- org.eclipse.jetty:jetty-jndi:jar:9.4.31.v20200723:compile
...
Other solutions were explicitly excluding apache-jsp from the project, but this is what is providing my JSP support, so that doesn't work for me.
I thought I could use an <exclusion>, but mvn dependency:tree | grep -i juli -C5 returns no results, so I'm not sure how I could add one here.
Update: Thanks to Joakim, I was able to significantly clean up my jar by <exclusion>ing a bunch of duplicate classes, to the point my only duplicates are about.html files and some overlap between jmockit and junit:
mvn org.basepom.maven:duplicate-finder-maven-plugin:check
...
[INFO] Checking compile classpath
[INFO] Checking runtime classpath
[INFO] Checking test classpath
[WARNING] Found duplicate and different resources in [org.eclipse.jdt:ecj:3.19.0, org.eclipse.jetty.toolchain:jetty-schemas:3.1.2, org.eclipse.jetty:apache-jsp:9.4.31.v20200723, org.eclipse.jetty:jetty-annotations:9.4.31.v20200723, org.eclipse.jetty:jetty-http:9.4.31.v20200723, org.eclipse.jetty:jetty-io:9.4.31.v20200723, org.eclipse.jetty:jetty-jndi:9.4.31.v20200723, org.eclipse.jetty:jetty-plus:9.4.31.v20200723, org.eclipse.jetty:jetty-security:9.4.31.v20200723, org.eclipse.jetty:jetty-server:9.4.31.v20200723, org.eclipse.jetty:jetty-servlet:9.4.31.v20200723, org.eclipse.jetty:jetty-util:9.4.31.v20200723, org.eclipse.jetty:jetty-webapp:9.4.31.v20200723, org.eclipse.jetty:jetty-xml:9.4.31.v20200723, org.eclipse.jgit:org.eclipse.jgit:1.0.0.201106090707-r]:
[WARNING] about.html
[WARNING] Found duplicate and different resources in [org.eclipse.jdt:ecj:3.19.0, org.eclipse.jetty.toolchain:jetty-schemas:3.1.2, org.eclipse.jetty:apache-jsp:9.4.31.v20200723, org.eclipse.jetty:jetty-annotations:9.4.31.v20200723, org.eclipse.jetty:jetty-http:9.4.31.v20200723, org.eclipse.jetty:jetty-io:9.4.31.v20200723, org.eclipse.jetty:jetty-jndi:9.4.31.v20200723, org.eclipse.jetty:jetty-plus:9.4.31.v20200723, org.eclipse.jetty:jetty-security:9.4.31.v20200723, org.eclipse.jetty:jetty-server:9.4.31.v20200723, org.eclipse.jetty:jetty-servlet:9.4.31.v20200723, org.eclipse.jetty:jetty-util:9.4.31.v20200723, org.eclipse.jetty:jetty-webapp:9.4.31.v20200723, org.eclipse.jetty:jetty-xml:9.4.31.v20200723, org.eclipse.jgit:org.eclipse.jgit:1.0.0.201106090707-r]:
[WARNING] about.html
[WARNING] Found duplicate and different classes in [com.googlecode.jmockit:jmockit:1.7, junit:junit:4.11]:
[WARNING] junit.framework.TestResult
[WARNING] org.junit.runner.Runner
[WARNING] Found duplicate and different resources in [org.eclipse.jdt:ecj:3.19.0, org.eclipse.jetty.toolchain:jetty-schemas:3.1.2, org.eclipse.jetty:apache-jsp:9.4.31.v20200723, org.eclipse.jetty:jetty-annotations:9.4.31.v20200723, org.eclipse.jetty:jetty-http:9.4.31.v20200723, org.eclipse.jetty:jetty-io:9.4.31.v20200723, org.eclipse.jetty:jetty-jndi:9.4.31.v20200723, org.eclipse.jetty:jetty-plus:9.4.31.v20200723, org.eclipse.jetty:jetty-security:9.4.31.v20200723, org.eclipse.jetty:jetty-server:9.4.31.v20200723, org.eclipse.jetty:jetty-servlet:9.4.31.v20200723, org.eclipse.jetty:jetty-util:9.4.31.v20200723, org.eclipse.jetty:jetty-webapp:9.4.31.v20200723, org.eclipse.jetty:jetty-xml:9.4.31.v20200723, org.eclipse.jgit:org.eclipse.jgit:1.0.0.201106090707-r]:
[WARNING] about.html
...
Unfortunately, this did not solve my issue.
Odds are high that you have multiple copies of org.apache.juli.logging.Log in your classpath and/or in multiple ClassLoader locations and it's getting confused.
Important: You really should fix your duplicate classes issue.
Since you are using maven, use one of the duplicate class finder plugins.
See: Find duplicated classes in classpath
Option B, once you have fixed all of your duplicate class issues, is to use the nolog classified artifact for apache-jsp.
https://search.maven.org/artifact/org.eclipse.jetty/apache-jsp/9.4.31.v20200723/jar
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jsp</artifactId>
<version>9.4.31.v20200723</version>
<classifier>nolog</classifier>
</dependency>
I had the same issue, but it was a bit different setup. A docker image with jetty was used and there were no direct connections to apache-jsp or anything that used org.apache.juli.logging.Log, so it was a bit weird why it was happening.
Upon further investigation, I noticed that I had both apache-jsp...jar (2 different versions of it) and gwt-dev.jar in the created docker image, under the WEB-INF/lib folder. I removed those jars and the problem was resolved.
This is a really old problem, so I guess it is probably not even relevant to people anymore, but just in case, wanted to write down that maybe you don't even have a direct dependency to apache-jsp, and the build system (gradle in my case) somehow fetches it (maybe via a indirect dependency on something).
Of course just removing jars from the docker file should be considered a dangerous action, as one may encouter other issues on runtime, so do this with caution.

java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createUnstarted()Lcom/google/common/base/Stopwatch

I've found an identical thread: NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch
but the solution seems not working for me.
The exception is:
java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createUnstarted()Lcom/google/common/base/Stopwatch
and is raised by:
at io.grpc.internal.GrpcUtil$4.get(GrpcUtil.java:566)
at io.grpc.internal.GrpcUtil$4.get(GrpcUtil.java:563)
Only Guava 20.0 seems present in my Classpath (I'm using Maven) so no older version can conflcits.
This is a snippet of my mvn dependency:tree output
[INFO] | +- com.google.cloud:google-cloud-core:jar:1.29.0:compile
[INFO] | | +- com.google.guava:guava:jar:20.0:compile
[INFO] | | +- com.google.http-client:google-http-client:jar:1.23.0:compile
If I search for Guava, this the only entry that I can see.
In the target folder the buil WAR => WEB-INF/lib has only guava-20.jar, no visible duplication.
Thanks in advance for any suggestions.

Maven parent hierarchy + dependencyManagement not transitive?

I thought dependencyManagement from parents were transitive aren't they?
Never see that explicitely in the doc, but it seemed obvious to me...
Here's what i have:
+-----------------------+
| Parent 1 |
|-----------------------|
| dependencyManagement: |
| lib1: 1.0.0 |
+-----------------------+
^
|
|
+-----------+-----------+
| Parent 2 |
|-----------------------|
| dependencyManagement: |
| lib2: 1.0.0 |
+-----------------------+
^
|
+-----------+-----------+
| Project A |
|-----------------------|
| dependencies: |
| lib1 |
| lib2 |
+-----------------------+
When i try to mvn install Project A, i get:
[ERROR] 'dependencies.dependency.version' for lib1-digester:jar is missing. # line XX, column YY
I also tried to add an entry of Parent 1 in the dependencyManagement of Parent 2 with the import scope, with no success..
How can my Project A have versions managed by all it's parent hierarchy?
It seems you are correct after reading the Maven Docs.
In general, all dependencies of those projects are used in your project, as are any that the project inherits from its parents, or from its dependencies, and so on.
Try to update to the latest version of Maven 3. IIRC, there were a couple of bugs in the inheritance of dependencyManagement elements.
A made a small example with other empty projects, and everything went fine...
Finally, there was something strange, here's what happened.
I was actually more like that:
+-----------------------+
| Parent 1 |
|-----------------------|
| dependencyManagement: |<----------------------+
| lib1: 1.0.0 | |
+-----------------------+ |
^ |
| +-------------+------------+
| | Project B |
+-----------+-----------+ |--------------------------|
| Parent 2 | | dependencies: |
|-----------------------| | somethingWrong: 1.0.0 |
| dependencyManagement: | +--------------------------+
| lib2: 1.0.0 |
+-----------------------+
^
|
+-----------+-----------+
| Project A |
|-----------------------|
| dependencies: |
| lib1 |
| lib2 |
+-----------------------+
There was an error in Project B's pom.xml
It shouldn't have any impact on my problem, but correcting that unrelated pom solved my problem...
Sorry for the wasted time

OutOfMemoryError: PermGen space when starting an embedded Tomcat

I have a library (vraptor-test) that does unit testing at my webservices in my maven project. In onder to run these tests, this library starts an embedded Tomcat.
Tomcat tomcat = new Tomcat();
I have checked the dependency tree, and the list below representss tomcat related jars added to my project by the test library:
+- org.apache.tomcat:tomcat-catalina:jar:7.0.23:compile
[INFO] | | +- org.apache.tomcat:tomcat-servlet-api:jar:7.0.23:compile
[INFO] | | +- org.apache.tomcat:tomcat-juli:jar:7.0.23:compile
[INFO] | | +- org.apache.tomcat:tomcat-annotations-api:jar:7.0.23:compile
[INFO] | | +- org.apache.tomcat:tomcat-api:jar:7.0.23:compile
[INFO] | | \- org.apache.tomcat:tomcat-util:jar:7.0.23:compile
[INFO] | +- org.apache.tomcat.embed:tomcat-embed-core:jar:7.0.23:compile
[INFO] | \- org.apache.tomcat:tomcat-jasper:jar:7.0.23:compile
[INFO] | +- org.apache.tomcat:tomcat-jsp-api:jar:7.0.23:compile
[INFO] | +- org.apache.tomcat:tomcat-el-api:jar:7.0.23:compile
[INFO] | +- org.eclipse.jdt.core.compiler:ecj:jar:3.7:compile
[INFO] | \- org.apache.tomcat:tomcat-jasper-el:jar:7.0.23:compile
When I run my test classes the error below pops up and the test doesn't even complete:
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space
Usually, I would make changes to setenv.bat under tomcat folder to increase the PermGem space, but, since I'm running an embedded Tomcat, I can't find its folder, only its jars.
I've tried increasing JVM memory in Eclipse (Window -> Preferences -> Java -> Installed JREs -> jdk -> Edit -> Default Vm Arguments) to -Xmx1024M -Xms1024M -XX:PermSize=2048m -XX:MaxPermSize=2048m but I'm still getting the same error.
Where can I change permgem space of my embedded tomcat?
Double-click on your Tomcat service under the Servers tab, and click on the "Open launch configuration" to open the Tomcat launch configuration window. Then, in their change your VM args (different from default VM args).
EDIT: If you are running a JAR from a Junit Test, you will need to change the VM Arguments in the Junit Launch configruation. You can view your Run/Debug launch configs and then edit the arguments tab.

Strange classCastException hibernate 3.5 glassfish

Hi I have a problem that I can't solve on my own.
I have a war file packaged in ear and running on glassfish 3.0.1 with hibernate 3.5 as JPA provider. I compile it with maven and deploy it with idea or manually.
Every other time I get a cast exception in my DAOs:
java.lang.ClassCastException: com.myproject.domain.entity.User cannot be cast to
com.myproject.domain.entity.User
Other times it works perfectly fine. There is no pattern in this behaviour.
Could someone shine some light on what is happening here?
Example method where the exception was thrown
at com.myproject.domain.dao.UserDAOImpl.checkUserSessionValid(UserDAOImpl.java:195)
public User checkUserSessionValid(String sessionId) {
User user = null;
EntityManager em = provider.entityManager();
try {
em.getTransaction().begin();
//Query q = em.createQuery("SELECT u FROM User u WHERE u.session.sessionId = :sessionId"); makes no difference :/
Query q = em.createQuery("SELECT u FROM User u WHERE u.session.sessionId = :sessionId",User.class);
q.setParameter("sessionId", sessionId);
user = (User) q.getSingleResult();
em.getTransaction().commit();
} catch (NoResultException ignored) {
} finally {
em.close();
}
return user;
}
My libraries
[INFO] +- org.apache.geronimo.specs:geronimo-jpa_2.0_spec:jar:1.0:provided
[INFO] +- javax.validation:validation-api:jar:1.0.0.GA:compile
[INFO] +- org.hibernate:hibernate-annotations:jar:3.5.1-Final:compile
[INFO] | +- org.hibernate:hibernate-core:jar:3.5.1-Final:compile
[INFO] | | +- antlr:antlr:jar:2.7.6:compile
[INFO] | | +- commons-collections:commons-collections:jar:3.2.1:compile
[INFO] | | +- dom4j:dom4j:jar:1.6.1:compile
[INFO] | | | \- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] | | \- javax.transaction:jta:jar:1.1:provided (scope managed from compile)
[INFO] | +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile
[INFO] | +- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.0.Final:compile
[INFO] | \- org.slf4j:slf4j-api:jar:1.5.2:compile
[INFO] +- org.hibernate:hibernate-entitymanager:jar:3.5.1-Final:compile
[INFO] | +- cglib:cglib:jar:2.2:compile
[INFO] | | \- asm:asm:jar:3.1:compile
[INFO] | \- javassist:javassist:jar:3.9.0.GA:compile
[INFO] +- org.hibernate:hibernate-validator:jar:4.1.0.Final:compile
[INFO] +- org.slf4j:slf4j-simple:jar:1.5.2:test
[INFO] +- mysql:mysql-connector-java:jar:5.1.13:test
[INFO] +- org.hsqldb:hsqldb:jar:2.0.0:test
Well, we sometimes had a similar error using JBoss. The problem there was a class loader (class loader repository) problem. When you have the same class loaded by multiple class loaders you can get that exception because a class loaded by loader 1 and a class loaded by loader 2 are not the same.
In our case we were able to solve this by enabling pass-by-value semantics, i.e. whenever some class loader (or app) border is crossed, the values are serialized/deserialized. Maybe you can check that for Glassfish as well (and look up how class loading is done there).
You could also check whether you have multiple copies or versions of your library in the classpath.
For all of you coming here via google, this problem is present in 4.3.6 and up: https://hibernate.atlassian.net/browse/HHH-9446
Downgrading to Hibernate 4.3.5 did the trick for our team.
Please check your Generated Sources if you are using Netbeans or any other IDE.
For example NetBeans will generate in your case a User_ class. It will do it for every other class as well within com.myproject.domain.entity package.
Check every file and remove imports from same package. Do not Clean your project since it will regenerate the code with the import statements from the same package. Just Build again and then deploy.
Just to be sure, check your all classes for the following statement (or equivalent) and remove if the import is from the same package:
import com.myproject.domain.entity.User;

Categories