I am working on a maven multi-module project with the following structure
project/
├── migration/
│ ├── src/
│ │ ├── main/
│ │ │ └── Migration.java
│ │ └── test
│ └── pom.xml
├── depends-on-migration/
│ ├── src/
│ │ ├── main (uses Migration.java - ok)
│ │ └── test (uses Migration.java - throws NoClassDefFoundError)
│ └── pom.xml (depends on migration)
└── pom.xml
The class can be used (see image), but cannot compile when I run mvnw package (see logs)
2022-12-17T14:22:56.025+08:00 INFO 13468 --- [ main] c.b.d.DependsOnMigrationApplicationTests : Starting DependsOnMigrationApplicationTests using Java 17.0.2 with PID 13468 (started by Joseph in Z:\bwgjoseph\maven-nested-multi-module-project\depends-on-migration)
2022-12-17T14:22:56.031+08:00 INFO 13468 --- [ main] c.b.d.DependsOnMigrationApplicationTests : No active profile set, falling back to 1 default profile: "default"
2022-12-17T14:22:57.289+08:00 INFO 13468 --- [ main] c.b.d.DependsOnMigrationApplicationTests : Started DependsOnMigrationApplicationTests in 1.534 seconds (process running for 2.498)
[ERROR] Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.493 s <<< FAILURE! - in com.bwgjoseph.dependsonmigration.DependsOnMigrationApplicationTests
[ERROR] test1 Time elapsed: 0.454 s <<< ERROR!
java.lang.NoClassDefFoundError: com/bwgjoseph/migration/Migration
at com.bwgjoseph.dependsonmigration.DependsOnMigrationApplicationTests.test1(DependsOnMigrationApplicationTests.java:17)
Caused by: java.lang.ClassNotFoundException: com.bwgjoseph.migration.Migration
at com.bwgjoseph.dependsonmigration.DependsOnMigrationApplicationTests.test1(DependsOnMigrationApplicationTests.java:17)
[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR] DependsOnMigrationApplicationTests.test1:17 NoClassDefFound com/bwgjoseph/migr...
[INFO]
[ERROR] Tests run: 2, Failures: 0, Errors: 1, Skipped: 0
This is a simplified example, can refer to repo (migration and depends-on-migration module)
I couldn't find anything similar, the closest I could find are cases where they are looking to use classes that are defined in migration/src/test but I am using migration/src/main
Glad to provide more information if required.
Thanks!
The problem stems from the fact that you use spring-boot-maven-plugin in both migration and depends-on-migration modules.
Spring Boot Maven Plugin produces an Uber-Jar, with a layout expected by Spring apps. The original jar (without dependencies) is renamed to migration-0.0.1-SNAPSHOT.jar.original
The structure of uber-jar
.
├── BOOT-INF
│ ├── classes
│ ├── classpath.idx
│ ├── layers.idx
│ └── lib
├── META-INF
├── migration-0.0.1-SNAPSHOT.zip
└── org
└── springframework
Your code is placed in BOOT-INF/classes - this is not a typical library layout, hence ClassNotFoundException.
See The Executable Jar Format for reference.
If you remove spring-boot-maven-plugin in migration project, mvn package passes.
Related
in my application i have many modules with resources.
project
|
└───moduleA
| |
│ └───resources
│ │
│ └───fileA
|
└───moduleB
| |
│ └───resources
│
└───moduleC
| |
| └───resources
| │
| |───fileA
| └───fileB
|
...
In moduleA and moduleB i use maven-remote-resources plugin to include resources (fileA and fileB) from moduleC. If the file with a given name exists in a moduleA or B, it should not be overwritten with the one from moduleC. Files get overwritten by default. How to configure the plugin to avoid that?
I am trying to create a Jar to be used as a Maven Repository
I have everything built out and all the classes are ready to go. Only problem is that the gradlew ./build is including the classes and resources from the test folder. I don't want these as part of the jar, especially the resource files under test.
So my question is, How do I exclude these files from my jar build task. I tried
tasks.named('jar'){
exclude('PATH/src/test/')
in my build.gradle but that didn't work
I am a newbiew at gradle and maven so any insight would help. Thanks!
Reference Material
build.gradle
plugins {
// Apply the java-library plugin for API and implementation separation.
id 'java-library'
id 'maven-publish'
}
group = 'com.project.tools'
version = '1.0.0'
repositories {
// Use Maven Central for resolving dependencies.
mavenCentral()
}
dependencies {
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:31.0.1-jre'
implementation platform('io.cucumber:cucumber-bom:7.1.0')
implementation 'io.cucumber:cucumber-java'
implementation 'io.cucumber:cucumber-junit-platform-engine'
implementation 'io.cucumber:cucumber-junit'
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
}
tasks.named('jar'){
manifest {
attributes('Implementation-Title': project.name,
'Implementation-Version': project.version)
}
}
File Structure
project/
├─ tools/
│ ├─ build/
│ │ ├─ classes/
│ │ │ ├─ new_folder/
│ │ │ │ ├─ main/
│ │ │ │ ├─ test/ #I Don't Want This Here, This Classes Do Not Need To Be Accessible
│ │ ├─ generated/
│ │ ├─ libs/
│ │ ├─ reports/
│ │ ├─ resources/
│ │ │ ├─ test/ #Would rather not have this entire folder
│ │ │ │ ├─ com.project.tools/
│ │ │ │ ├─ test.properties # Definitely Do Not Want This Included
│ │ ├─ test-results/
│ │ ├─ tmp/
│ ├─ src/
│ │ ├─ main/
│ │ │ ├─ java/
│ │ │ │ ├─ com.project.tools/
│ │ │ │ │ ├─ MyClasses.java
│ │ │ ├─ resources/
│ │ ├─ test/
│ │ │ ├─ java/
│ │ │ │ ├─ com.project.tools/
│ │ │ │ │ ├─ MyTestClasses.java
│ │ │ ├─ resources/
│ ├─ build.gradle
Gradle does the right thing by default, there is no need to manually exclude test classes/resources from the jar.
I wrote simple Java application using Spring framework and Thymeleaf. On my IDE it's working complettly fine but when I'm making JAR artifact and exporting it to my linux server it's booting but I'm getting this errors:
02:56:06.447 [main] INFO com.ibcs.rfid.RfidApplication - Started RfidApplication in 142.158 seconds (JVM running for 151.664)
Jul 15, 2021 2:56:10 AM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring DispatcherServlet 'dispatcherServlet'
02:56:10.948 [http-nio-8080-exec-1] INFO org.springframework.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
02:56:10.954 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected StandardServletMultipartResolver
02:56:10.959 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected AcceptHeaderLocaleResolver
02:56:10.964 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected FixedThemeResolver
02:56:11.171 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator#1db0c88
02:56:11.251 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected org.springframework.web.servlet.support.SessionFlashMapManager#1384aac
02:56:11.257 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
02:56:11.261 [http-nio-8080-exec-1] INFO org.springframework.web.servlet.DispatcherServlet - Completed initialization in 308 ms
02:56:11.638 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/", parameters={}
02:56:11.745 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.ibcs.rfid.controllers.ServiceControllers#loginForm(Model)
02:56:12.994 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.view.ContentNegotiatingViewResolver - Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, application/xml;q=0.9, */*;q=0.8]
02:56:13.003 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.view.InternalResourceView - View name 'login', model {authentication=com.ibcs.rfid.models.Authentication#14147d2, org.springframework.validation.BindingResult.authentication=org.springframework.validation.BeanPropertyBindingResult: 0 errors}
02:56:13.065 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.view.InternalResourceView - Forwarding to [login]
02:56:13.265 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - "FORWARD" dispatch for GET "/login", parameters={}
02:56:13.383 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped to ResourceHttpRequestHandler [Classpath [META-INF/resources/], Classpath [resources/], Classpath [static/], Classpath [public/], ServletContext [/]]
02:56:13.434 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.resource.ResourceHttpRequestHandler - Resource not found
02:56:13.441 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Exiting from "FORWARD" dispatch, status 404
02:56:13.461 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 404 NOT_FOUND
02:56:13.480 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - "ERROR" dispatch for GET "/error", parameters={}
02:56:13.549 [http-nio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
My files tree:
├───.idea
│ ├───artifacts
│ └───libraries
├───.mvn
│ └───wrapper
├───out
│ └───artifacts
│ └───rfid_jar
├───src
│ ├───main
│ │ ├───java
│ │ │ ├───com
│ │ │ │ └───ibcs
│ │ │ │ └───rfid
│ │ │ │ ├───controllers
│ │ │ │ ├───models
│ │ │ │ └───storers
│ │ │ └───META-INF
│ │ └───resources
│ │ ├───jsons
│ │ ├───static
│ │ │ ├───css
│ │ │ ├───img
│ │ │ └───js
│ │ └───templates
│ └───test
│ └───java
│ └───com
│ └───ibcs
│ └───rfid
└───target
├───classes
│ ├───com
│ │ └───ibcs
│ │ └───rfid
│ │ ├───controllers
│ │ ├───models
│ │ └───storers
│ ├───jsons
│ ├───static
│ │ ├───css
│ │ ├───img
│ │ └───js
│ └───templates
├───generated-sources
│ └───annotations
├───generated-test-sources
│ └───test-annotations
└───test-classes
└───com
└───ibcs
└───rfid
And my application.properties content:
spring.thymeleaf.check-template-location=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
Also here is part of my Controller:
#GetMapping("/")
public String loginForm(Model model)
{
model.addAttribute("authentication", new Authentication());
return "login";
}
Any ideas how can I fix it?
Also I'm limited to only .jar file cause It have to run on Zebra FX9600
Solution (from comments):
Build it with maven
Thanks M. Deinum
I've created my minimal custom Karaf distribution:
mvn archetype:generate \
-DarchetypeGroupId=org.apache.karaf.archetypes \
-DarchetypeArtifactId=karaf-assembly-archetype \
-DarchetypeVersion=4.1.4 \
-DgroupId=my.karaf \
-DartifactId=karaf-custom-distribution \
-Dversion=1.0-SNAPSHOT \
-Dpackage=my.karaf.distribution
cd karaf-custom-distribution
mvn install
cd target/assembly/bin/
./karaf
Then tried to install Keycloak feature into it manually:
feature:repo-add mvn:org.keycloak/keycloak-osgi-features/3.4.3.Final/xml/features
feature:install keycloak-jetty9-adapter
feature:install keycloak
The last command gives me an error back. Any suggestions how to solve this dependency error?
Error executing command: Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity=keycloak; type=karaf.feature; version="[3.4.3.Final,3.4.3.Final]"; filter:="(&(osgi.identity=keycloak)(type=karaf.feature)(version>=3.4.3.Final)(version<=3.4.3.Final))" [caused by: Unable to resolve keycloak/3.4.3.Final: missing requirement [keycloak/3.4.3.Final] osgi.identity; osgi.identity=keycloak-osgi-adapter; type=karaf.feature [caused by: Unable to resolve keycloak-osgi-adapter/3.4.3.Final: missing requirement [keycloak-osgi-adapter/3.4.3.Final] osgi.identity; osgi.identity=http-whiteboard; type=karaf.feature; version="[2.3.0,4.0.0)"]]
karaf#root()> list
START LEVEL 100 , List Threshold: 50
ID │ State │ Lvl │ Version │ Name
────┼────────┼─────┼─────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────
125 │ Active │ 50 │ 2.6.0 │ Apache Commons IO
126 │ Active │ 50 │ 1.0.1 │ Apache Aries Blueprint Web OSGI
127 │ Active │ 50 │ 4.1.4 │ Apache Karaf :: Diagnostic :: Boot
128 │ Active │ 50 │ 4.1.4 │ Apache Karaf :: Profile :: Core
129 │ Active │ 50 │ 4.1.4 │ Apache Karaf :: Tooling :: Utils
130 │ Active │ 50 │ 4.1.4 │ Apache Karaf :: OSGi Services :: Event
131 │ Active │ 50 │ 1.3.5 │ Jolokia Agent
132 │ Active │ 50 │ 2.20.2 │ camel-blueprint
133 │ Active │ 80 │ 2.20.2 │ camel-commands-core
134 │ Active │ 50 │ 2.20.2 │ camel-core
135 │ Active │ 80 │ 2.20.2 │ camel-karaf-commands
139 │ Active │ 80 │ 1.56 │ bcpkix
140 │ Active │ 80 │ 1.56 │ bcprov
141 │ Active │ 80 │ 2.8.9 │ Jackson-annotations
142 │ Active │ 80 │ 2.8.9 │ Jackson-core
143 │ Active │ 80 │ 2.8.9 │ jackson-databind
144 │ Active │ 80 │ 3.4.3.Final │ Keycloak Adapter Core
145 │ Active │ 80 │ 3.4.3.Final │ Keycloak Adapter SPI
146 │ Active │ 80 │ 3.4.3.Final │ KeyCloak Authz: Client API
147 │ Active │ 80 │ 3.4.3.Final │ Keycloak Common
148 │ Active │ 80 │ 3.4.3.Final │ Keycloak Core
149 │ Active │ 80 │ 3.4.3.Final │ Keycloak Jetty Adapter SPI
150 │ Active │ 80 │ 3.4.3.Final │ Keycloak Jetty Core Integration
151 │ Active │ 80 │ 3.4.3.Final │ Keycloak Jetty 9.2.x Integration
152 │ Active │ 80 │ 3.4.3.Final │ Keycloak OSGI Thirdparty
I am following this example of a Hello World Wicket application
https://www.ibm.com/developerworks/web/library/wa-aj-wicket/
In particular I placed HelloWorld.html in my source directory next to HelloWorld.java.
My file structure looks like this:
$ tree
.
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── wicket
│ │ │ ├── HelloWorld.html
│ │ │ ├── HelloWorld.java
│ │ │ └── HelloWorldApplication.java
│ │ ├── resources
│ │ └── webapp
│ │ └── WEB-INF
│ │ └── web.xml
│ └── test
│ └── java
└── wicketTest.iml
However when I compile this to a war file, and load in Jetty, i recieve this error, in the browser:
Unexpected RuntimeException
Last cause: Can not determine Markup. Component is not yet connected to a parent. [Page class = com.example.wicket.HelloWorld, id = 4, render count = 1]
Stacktrace
Root cause:
org.apache.wicket.markup.MarkupNotFoundException: Can not determine Markup. Component is not yet connected to a parent. [Page class = com.example.wicket.HelloWorld, id = 4, render count = 1]
at org.apache.wicket.Component.getMarkup(Component.java:737)
at org.apache.wicket.Component.internalRender(Component.java:2344)
at org.apache.wicket.Component.render(Component.java:2307)
at org.apache.wicket.Page.renderPage(Page.java:1010)
When I look in the war file I notice that the html file is missing:
$ tar tvf target/wicketTest-1.0-SNAPSHOT.war
drwxrwxrwx 0 0 0 0 Aug 22 14:50 META-INF/
-rwxrwxrwx 0 0 0 128 Aug 22 14:50 META-INF/MANIFEST.MF
drwxrwxrwx 0 0 0 0 Aug 22 14:50 WEB-INF/
drwxrwxrwx 0 0 0 0 Aug 22 14:50 WEB-INF/classes/
drwxrwxrwx 0 0 0 0 Aug 22 14:50 WEB-INF/classes/com/
drwxrwxrwx 0 0 0 0 Aug 22 14:50 WEB-INF/classes/com/example/
drwxrwxrwx 0 0 0 0 Aug 22 14:50 WEB-INF/classes/com/example/wicket/
drwxrwxrwx 0 0 0 0 Aug 22 14:50 WEB-INF/lib/
-rwxrwxrwx 0 0 0 608 Aug 22 14:50 WEB-INF/classes/com/example/wicket/HelloWorld.class
-rwxrwxrwx 0 0 0 551 Aug 22 14:50 WEB-INF/classes/com/example/wicket/HelloWorldApplication.class
-rwxrwxrwx 0 0 0 25962 Aug 21 16:07 WEB-INF/lib/slf4j-api-1.6.4.jar
-rwxrwxrwx 0 0 0 2126440 Aug 21 16:07 WEB-INF/lib/wicket-core-6.10.0.jar
-rwxrwxrwx 0 0 0 86671 Aug 21 16:07 WEB-INF/lib/wicket-request-6.10.0.jar
-rwxrwxrwx 0 0 0 415858 Aug 21 16:07 WEB-INF/lib/wicket-util-6.10.0.jar
-rwxrwxrwx 0 0 0 690 Aug 22 13:22 WEB-INF/web.xml
drwxrwxrwx 0 0 0 0 Aug 22 14:50 META-INF/maven/
drwxrwxrwx 0 0 0 0 Aug 22 14:50 META-INF/maven/wicketTest/
drwxrwxrwx 0 0 0 0 Aug 22 14:50 META-INF/maven/wicketTest/wicketTest/
-rwxrwxrwx 0 0 0 675 Aug 22 08:52 META-INF/maven/wicketTest/wicketTest/pom.xml
-rwxrwxrwx 0 0 0 112 Aug 22 14:50 META-INF/maven/wicketTest/wicketTest/pom.properties
How do I specify in my POM file to include the html file?
My POM right now is minimal:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>wicketTest</groupId>
<artifactId>wicketTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-core</artifactId>
<version>6.10.0</version>
</dependency>
</dependencies>
</project>
The solution, if you want your HTML in the wicket best practice place (with your classes) is to add this to the build section of your pom.
<build>
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
</resource>
<resource>
<filtering>false</filtering>
<directory>src/main/java</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</build>
</project>
You should put you HelloWorld.html file into src/main/webapp folder. This way it will be included in the war file
If using Maven, see David Williams' answer. If using Gradle, see this answer.
Include the following in your build.gradle file:
sourceSets {
main {
resources {
srcDirs += ['src/main/java']
includes = ["**"]
// or specifically: includes = ["**/*.html"]
}
}
}
This ensures that the HTML files will be added to the WAR file.