Wicket + Spring Boot + .war file deployment - wicket

Building on the example here: https://github.com/Pentadrago/spring-boot-example-wicket
And taking into account the jar-to-war guide here: https://spring.io/guides/gs/convert-jar-to-war/
I'd like to convert my existing Wicket + Spring (using data-jpa and security) to Spring Boot. It's been fairly easy to get the fat-jar setup to work, but it has so far proved impossible for me to convert this setup into a .war file to deploy in Tomcat.
The issue stems from the conflicting instructions to:
on the one hand extends org.springframework.boot.context.web.SpringBootServletInitializer from a non-#Configuration class for the jar-to-war conversion guide,
while on the other implements org.springframework.boot.context.embedded.ServletContextInitializer for a #Configuration marked class for the fat-jar Wicket example.
I've not been able to align the two such that I get a working application both when debugging with the embedded container, and when deployed as .war in Tomcat.
Can anyone tell me how I can setup a spring-boot enabled wicket application that I can deploy as a .war file?

What I did and got the application to work was the following:
I checked out the example project https://github.com/Pentadrago/spring-boot-example-wicket that you posted.
Then following the code on the https://spring.io/guides/gs/convert-jar-to-war/ guide all I did was to make the following changes:
Change build.gradle to:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.2.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
apply plugin: 'war'
jar {
version = '0.0.1'
}
repositories {
mavenCentral()
}
configurations {
providedRuntime
}
dependencies {
compile(
"org.springframework.boot:spring-boot-starter",
"org.springframework.boot:spring-boot-starter-logging",
"org.springframework:spring-web:4.0.3.RELEASE",
"org.apache.wicket:wicket-spring:6.15.0",
)
testCompile(
"org.springframework.boot:spring-boot-starter-test",
)
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
}
Add the following class:
HelloWebXml.java
package spring.boot.example.wicket;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
public class HelloWebXml extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WicketWebApplication.class);
}
}
Those where the only changes I made and deployed to Tomcat 7 without any problems.
Here is the excerpt from the log that shows that wicked got started
2014-08-27 20:57:41.396 INFO 2708 --- [on(3)-127.0.0.1] org.apache.wicket.Application : [wicket-filter] init: Wicket core library initializer
I am not sure what your source of confusion is but you have to understand that SpringBootServletInitializer and ServletContextInitializer serve different purposes.

Related

eclipse ResolutionException: Modules A and B export package P to module C

I try to migrate my java8 spring project to java11. Now I get the following exception when I try to run it from eclipse:
Error occurred during initialization of boot layer
java.lang.module.ResolutionException: Modules java.activation and jakarta.activation export package javax.activation to module spring.boot.starter.web
Under Referenced Libraries I only found jakarta.activation-api-1.2.2.jar which exports the package javax.activation. The other module java.activation I have no clue where it comes from. From the name it should be inside JavaSE-11/JDK ? I checked the entry JRE System Library but I don't see that package there.
Now the curios thing is with Gradle 6.5 I can run the project using "gradlew bootRun" and it executes nicely. However in eclipse it fails with the errror.
So in eclipse I just tried to remove Jakarta.activation by Right-click remove from build path. Trying to import anything from javax.activation then gives me "import can't be resolved", fine so far. However running still complains with the above ResolutionException.
So to fix the issue:
Where is the other sourcecode that exports javax.activation package? And how do I find that?
How can I prevent eclipse from having those two modules at runtime?
Can I exclude the module in gradle, such that the project works after running "gradlew eclipse" like always?
Thanks for your help! I spent hours searching and didn't find anything useful so far.
The build.gradle looks as following:
plugins {
id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
id 'eclipse'
}
group = 'example'
version = '0.3.0'
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
configurations.all {
// fix multiple slf4j dependencies are present
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
//TODO: 1st approach to fix ResolutionException
//exclude group: 'jakarta.activation', module: 'jakarta.activation-api'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:2.3.1.RELEASE'
implementation ('org.springframework.boot:spring-boot-starter-web:2.3.1.RELEASE') {
//TODO: 2nd approach to fix ResolutionException
exclude group: 'jakarta.activation', module: 'jakarta.activation-api'
}
implementation 'org.springframework.boot:spring-boot-starter-security:2.3.1.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.3.1.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-actuator:2.3.1.RELEASE'
implementation 'mysql:mysql-connector-java:5.1.46'
implementation 'com.querydsl:querydsl-jpa:4.1.4'
implementation 'com.querydsl:querydsl-apt:4.1.4:jpa'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'org.flywaydb:flyway-core:5.2.4'
compileOnly 'org.springframework.boot:spring-boot-devtools:2.3.1.RELEASE'
// https://mvnrepository.com/artifact/org.apache.odftoolkit/simple-odf
implementation 'org.apache.odftoolkit:simple-odf:0.8.2-incubating'
// https://mvnrepository.com/artifact/org.apache.commons/commons-text
implementation 'org.apache.commons:commons-text:1.1'
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
implementation 'org.apache.commons:commons-lang3:3.7'
// https://mvnrepository.com/artifact/org.apache.commons/commons-csv
implementation 'org.apache.commons:commons-csv:1.5'
// https://mvnrepository.com/artifact/org.apache.commons/commons-collections4/4.3
implementation 'org.apache.commons:commons-collections4:4.3'
implementation 'javax.validation:validation-api:2.0.0.Final'
// Dependencies that are no longer in java11
// implementation 'javax.xml.bind:jaxb-api:2.3.0'
// implementation 'com.sun.xml.bind:jaxb-core:2.3.0'
// implementation 'com.sun.xml.bind:jaxb-impl:2.3.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.5.2'
}
eclipse {
classpath {
downloadJavadoc = true
downloadSources = true
}
}
Other links I found but didn't help me so far:
https://dba-presents.com/index.php/jvm/java/159-error-java-module-xyz-reads-package-org-apache-commons-logging-from-both-commons-logging-and-jcl-over-slf4j
Modules A and B export package some.package to module C in Java 9
Two Modules exports the same package (Spring)
https://forum.byte-welt.net/t/resolutionexception-module-a-module-b-to-module-c/20843/2
Ok I found part of an answer while trying to create an example to reproduce the issue.
First I tried to clean the project to make sure nothing bad is cached in eclipse:
gradlew clean eclipse
Still the problem occured.
Now I went full ham and removed all build files, .project, .classpath and reran gradlew eclipse and while adding a new run configuration the project now starts fine.
So probably blame the cache of the run-configuration.
Maybe this or the cross-links to other posts about the same issue still helps someone.

Adding custom jars to camel-k integration

Lets say I have utility jar called validation.jar
which can validate some string to be forwarded.
How can I add this validation.jar along with camel-k integration in minkube.
example :
import com.validation.Util;
import org.apache.camel.builder.RouteBuilder;
public class MyRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
//from("timer:tick").log(Util.validate("dummy message - new"));
from("timer:tick").log("dummy message - new");
}
}
to get com.validation.Util class we need validation.jar available with camel-k. How to provide that.
There is just one way of achieving your goal. Store your java classses with pom.xml file for building jar in github repository. After that you can use Jitpack.io. Jitpack will build and store jar file in its registry. Finally, you can use as dependency on kamel run command.
Starting from camel-k 1.9.x, it is possible to provide a dependency located in the local filesystem by using the file:// prefix when specifying the dependency, like the next example:
kamel run -d file://path/to/validation.jar MyRoute.java

Running Vert.x (w/ES4X) via Eclipse

This question is a follow-up to:
Running Vuetify on Vert.x (w/ES4X)
I would like to be able to run ES4X via Eclipse (instead of NPM). I'm not exactly sure if it's possible or how to wire it in.
Let's say I have the following build.gradle.file
plugins {
id 'java'
id 'application'
id 'com.johnrengleman.shadow' version "5.0.0"
}
sourceCompatibility='1.8'
mainClassName='io.vertx.core.Launcher'
repositories {
mavenCentral()
}
dependencies {
implementation 'io.vertx:vertx-core:3.7.1'
implementation 'io.vertx:vertx-web:3.7.1'
implementation 'io.vertx:vertx-lang-js:3.7.1'
// implementation 'io.reactiverse:es4x:0.8.0'
// implementation 'io.reactiverse:es4x-pm:0.8.0'
}
processResources {
from '/src/main/js'
}
shadowJar {
classifier = 'fat'
manifest {
attributes 'Main-Verticle' : 'index.js'
}
mergeServiceFiles {
include 'META-INF/services/io.vertx.core.spi.VerticleFactory'
}
}
and my src/main/js/index.js looks like the one from the other referenced post:
import { Router, StaticHandler } from '#vertx/web';
const app = Router.router(vertx);
app.get().handler(StaticHandler.create("dist"));
vertx.createHttpServer().requestHandler(app).listen(8080);
If I create an executable jar via shadowJar, I get javax.script.ScriptExceptions due to Nashorn choking on the index.js contents (as expected).
If I uncomment the es4x implementation in the gradle build, I get ClassNotFound exceptions for org.graalvm.polyglot.io.FileSystem
So how would I correctly modify this app to take advantage of ES4X? I guess the equivalent of what the 'es4x init' would do?
Say that you have your es4x application and a package.json, when you execute:
npm install
You will get inside node_modules a few extra folders:
.bin
.lib
In the .bin directory there is a es4x-launcher.jar file you can use to start your application from Eclipse. It will refer to the dependencies which are unpacked to the .lib dir. In order to make things work fine the same JVM you have when running the npm install command should be used in eclipse. Otherwise you might end up missing dependencies. This is the case when running graalvm which will not require graaljs dependencies or when running on jdk8 which will not require jvmci dependencies.

Kotlin setup via gradle on eclipse

Struggling to get Kotlin running on eclipse.
I've started new graddle project. Added dependencies as prescribed on kotlin's site.
Build passes without errors.
I've created 'main.kt' file under src/java/main with:
fun main(args: Array<String>) {
println("foo")
}
BUT, I have two problems:
1. anything from kotlin e.g. println highlighted as 'unresolved reference'.
2. I can't run a program - Error: Could not find or load main class MainKt (rightclick on main.kr run as 'kotlin application')
If I create 'new kotlin project' everything works.
my graddle build script:
plugins {
id "org.jetbrains.kotlin.jvm" version "1.1.2-2"
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
//api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:21.0'
testImplementation 'junit:junit:4.12'
compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.2-2"
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
compile "org.jetbrains.kotlin:kotlin-reflect"
testCompile "org.jetbrains.kotlin:kotlin-test"
testCompile "org.jetbrains.kotlin:kotlin-test-junit"
}
sourceSets {
main.java.srcDirs = ['src/main/java']
main.kotlin.srcDirs = ['src/main/java', 'src/main/kotlin']
main.resources.srcDirs = ['src/main/resources']
}
What did I do wrong?
I've zero Java knowledge if that helps, so probably I've made some trivial error.
UPDATE:
Installed a Spring plugin and generated a new web app via it including gradle.
But Kotlin behaves unpredictably there too.
At first I was not able to run it as run as Kotlin application and it errored with main could not be found, BUT sometimes it run and crashed immediately. It started to launch and crash after I've deleted and edited classes, tried creating it under other package, removing and adding Kotlin (I can't reproduce sequence to make it work again).
Fun part that gradle boot build launches everything and all works it somehow finds Kotlin's main.
Probably some issue with Kotlin plugin itself (it's load probably depends on certain events that doesn't always fire)
Add the following to your configuration:
apply plugin: 'eclipse'
eclipse {
classpath {
containers 'org.jetbrains.kotlin.core.KOTLIN_CONTAINER'
}
}
See https://gitlab.com/frnck/kotlin-gradle-eclipse for a working configuration.
I'd like to add to frnck answer that this is only part of the solution. I also had to add these lines:
eclipse.project {
buildCommand 'org.jetbrains.kotlin.ui.kotlinBuilder'
natures 'org.jetbrains.kotlin.core.kotlinNature'
natures 'org.eclipse.jdt.core.javanature'
linkedResource name: 'kotlin_bin', type: '2', locationUri: 'org.jetbrains.kotlin.core.filesystem:/aio/kotlin_bin'
}
For Eclipse 2018-12 and kotlin 1.3 the solution was a combination of other answers plus some additional settings file:
eclipse {
classpath {
//Adds the kotlin container to the classpath
containers 'org.jetbrains.kotlin.core.KOTLIN_CONTAINER'
//Fixes the right output path
defaultOutputDir = file('bin')
//Make all src folders output in the same output folder (default)
file {
whenMerged {
// use default Output for all source-folders. see also defaultOutputDir per project
entries.each { source ->
// only Source-folders in the project starting with '/' are project-references
if (source.kind == 'src' && !source.path.startsWith('/')) {
source.output = null
}
}
}
}
}
project{
buildCommand 'org.jetbrains.kotlin.ui.kotlinBuilder'
//Fixes the natures
natures 'org.jetbrains.kotlin.core.kotlinNature'
natures 'org.eclipse.jdt.core.javanature'
//Links the kotlin_bin folder (generated class files)
linkedResource name: 'kotlin_bin', type: '2', locationUri: "org.jetbrains.kotlin.core.filesystem:/${project.name}/kotlin_bin".toString()
file{
whenMerged{
def kotlinPrefs = file('.settings/org.jetbrains.kotlin.core.prefs')
def jdkHome = System.properties.'java.home'
if(!(jdkHome)){
throw new GradleException('No JDK home available for setting up Eclipse Kotlin plugin, setup env "java.home" or update this script.')
}
kotlinPrefs.write """\
codeStyle/codeStyleId=KOTLIN_OFFICIAL
codeStyle/globalsOverridden=true
compilerPlugins/jpa/active=true
compilerPlugins/no-arg/active=true
compilerPlugins/spring/active=true
eclipse.preferences.version=1
globalsOverridden=true
jdkHome=$jdkHome
""".stripIndent()
}
}
}
}
I would like to add to Felipe Nascimento's answer that the location of the .settings folder does not yet exist. It works when the line below is inserted into that answer.
def kotlinPrefs = file("../${project.name}/.settings/org.jetbrains.kotlin.core.prefs".toString())
I have found that the JAVA_HOME environment variable that is set when your run this task ;
gradle cleanEclipse eclipse
is the one that is included in the Eclipse BuildPath

Gradle (tomcat-plugin): tomcatRun cannot execute GWT JS

I am trying to build a GWT enabled web application with Gradle (on Ubuntu Linux).
I have configured everything, and Gradle manages to successfully build the application, but when I run the task "tomcatRun", I can only see a blank page, which is a result of GWT javascript not executing (if I view the page source, it is there). No errors, no warnings from Tomcat, just that blank page.
However, when I run "tomcatRunWar", everything works perfectly. I can't figure out what might be wrong or why might this happen.
This is my gradle.build file:
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'tomcat'
apply plugin: 'eclipse-wtp'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.gradle.api.plugins:gradle-tomcat-plugin:1.0"
}
}
repositories {
mavenCentral()
}
dependencies {
/* Tomcat plugin dependencies */
def tomcatVersion = '7.0.47'
tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}"
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") {
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
}
/* Google Web Toolkit */
def gwtVersion = '2.5.1'
providedCompile "com.google.gwt:gwt-user:${gwtVersion}"
providedCompile "com.google.gwt:gwt-dev:${gwtVersion}"
runtime "com.google.gwt:gwt-servlet:${gwtVersion}"
/* Spring Security */
def springVersion = '3.1.4.RELEASE'
compile "org.springframework.security:spring-security-web:${springVersion}"
compile "org.springframework.security:spring-security-config:${springVersion}"
}
/* Task to compile the client package GWT code to JavaScript */
task gwtCompile (dependsOn: classes, type: JavaExec) {
buildDir = "${project.buildDir}/gwt"
extraDir = "${project.buildDir}/extra"
inputs.source sourceSets.main.java.srcDirs
inputs.dir sourceSets.main.output.resourcesDir
outputs.dir buildDir
doFirst {
file(buildDir).mkdirs()
}
main = "com.google.gwt.dev.Compiler"
classpath {
[
sourceSets.main.java.srcDirs, // Java source
sourceSets.main.output.resourcesDir, // Generated resources
sourceSets.main.output.classesDir, // Generated classes
sourceSets.main.compileClasspath, // Dependencies
]
}
args = [
'<package_path_to_GWT_module>', // Our GWT module
'-war', buildDir,
'-logLevel', 'INFO',
'-localWorkers', '2',
'-compileReport',
'-extra', extraDir,
]
maxHeapSize = '256M'
}
/* Make the war plugin depend on the gwtCompile task */
war.dependsOn gwtCompile
/* Include the contents of the GWT compilation in the generated WAR file */
war {
from gwtCompile.buildDir
}
/* Configure the eclipse plugin in case it is used */
eclipse {
project {
natures 'com.google.gwt.eclipse.core.gwtNature'
buildCommand 'com.google.gdt.eclipse.core.webAppProjectValidator'
buildCommand 'com.google.gwt.eclipse.core.gwtProjectValidator'
}
classpath {
containers 'com.google.gwt.eclipse.core.GWT_CONTAINER'
}
}
My directory tree looks like this:
ProjectHome
-- src
-- main
-- java
-- <packages>
-- webapp
-- WEB-INF
-- web.xml
-- index.html
-- test
-- build.gradle
I have also compared the resulting WAR's directory tree with the one used by the 'tomcatRun' task (build/libs/ProjectName) and they seem identical.
Does anyone have any ideas for this?
// Edit: Actually, it does not display an empty page, it just can't execute the GWT Javascript, to assign content to the only div in body.
OK, found the solution.
You actually have to copy the needed files into the src/main/webapp directory (or make the build script do that or even better configure the tomcat-plugin to read the files from elsewhere - if that is possible), because tomcatRun reads the files from there. I was expecting it to read them from where the WAR file lies in (build/libs), but this is not the case.
So, the best option here, given that the GWT plugin is still a work in progress, is to use the tomcatRunWar option.