Where to place init.sql file for a java application - spring

Currently we have the following project structure:
root
|_____ api
|_____ common
|______ repository
|_______ src
|_____ main
|_______ kotlin
|_______ sql
|____ init.sql
|_____ test
|_______ kotlin
|_______ ...
|____ Test.kt
|_______ build.gradle.kts
|______ test-utils
|_________ src
|_______...
|_____ package
|________ TestDataSourceConfiguration.kt
|______ ...
|_____ runner
|______ src
|_____ test
|______ ...
|____ TestRunner.kt
TestDataSourceConfiguration.kt creates connection to h2 database with init script from init.sql.
#TestConfiguration
#PropertySource("classpath:database-test.properties")
open class TestDataSourceConfiguration(
#Autowired private val environment: Environment,
) {
#Bean
open fun dataSource(): DataSource {
....
val url = "jdbc:h2://~test;INIT=RUNSCRIPT FROM 'src/main/sql/init.sql'"
....
}
So this works good in Test.kt, but when run tests from TestRunner.kt it fails, because user.dir points to root/runner and init.sql can't be found
I was trying to set for all subprojects new property which points to the root directory of a rootProject... but no avail
Any thoughts how to do this properly?

You can create a data.sql file in your src/main/resources folder and it will be automatically executed on startup.
You can also create a schema.sql to init your database schema if hibernate don’t.
If you still want to specify the runscript you can put it in src/main/resources and do the following : RUNSCRIPT FROM 'classpath:init.sql'

Related

Error while trying to get build script read the java file - Could not resolve all artifacts for configuration ':classpath'

I'm trying to follow this by adding my own custom java file into the classpath
https://github.com/gigaSproule/swagger-gradle-plugin#model-converters
This is shown in the example above
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.custom:model-converter:1.0.0'
}
}
...
swagger {
apiSource {
...
modelConverters = [ 'com.custom.model.Converter' ]
}
}
This is my code
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("com.test.app.profile.component.MyOpenApiCustomiser:1.0.0")
}
}
swagger {
apiSource {
...
modelConverters = [ 'com.test.app.profile.component.MyOpenApiCustomiser' ]
}
}
This is the error I'm getting
A problem occurred configuring root project 'profile'.
> Could not resolve all artifacts for configuration ':classpath'.
> Could not find com.test.app.profile.component.MyOpenApiCustomiser:1.0.0:.
Required by:
project :
Possible solution:
- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
I tried removing 1.0.0
Caused by: org.gradle.api.IllegalDependencyNotation: Supplied String module notation 'com.test.app.profile.component.MyOpenApiCustomiser' is invalid. Example notations: 'org.gradle:gradle-core:2.2', 'org.mockito:mockito-core:1.9.5:javadoc'
Not sure how I would get my build script to the use the MyOpenApiCustomiser in my spring boot application
Is there any other way or how to fix this?
The classpath dependency given in the buildscript.dependencies {} block needs to be a external library, given in the standard group:modulde:version notation; in the example from github project it's "com.custom : model-converter : 1.0.0" ( it's a "fake" library, does not really exist in maven central repo, it's just an example)
In your case, it seems you try to refer your class MyOpenApiCustomiser as the classpath library , which cannot work. It needs to be a real library.
If you want to use your own Converter, you'll need to implement it in another library/module, publish it to a private repository and then consume it in your buildscript classpath.
Another simpler way, would be to implement this converter as a class within the buildSrc project: these classes will then be automatically available in your build script classpath, and you can use it in the apiSource configuration.
Sample:
In your buildSrc project
build.gradle
plugins {
id("java")
}
repositories {
mavenCentral()
}
dependencies {
implementation "io.swagger:swagger-core:1.6.2"
}
Your custom ModelConverter class goes under src/main/java, e.g. com.sample.MyCustomConverter
In your root build.gradle script:
You can reference your MyCustomConverter class, it's already available in the script classpath, no need to define a classpath dependency in buildscript
swagger {
apiSource {
modelConverters = [ 'com.sample.MyCustomConverter' ]
// ....

Error with Building Fatjar Using Kotlin DSL

I am trying to build a fatjar using ShadowJar. My app and gradle code are below. I'm using Gradle 5.0 for the build. When I run ./gradlew run, the code works. When I run 'gradle shadowjar', and run the fatjar using 'java -jar' in the 'build/lib' folder, I get the below error.
I'm guessing the dependencies are not getting loaded in the fatjar? I have also used Groovy to build the Gradle file, and I get the same error.
Am I correct in that I am not including all of the dependencies in the fatjar file? If that is the case, any idea on how to modify the Gradle file to make sure this is included?
Gradle Kotlin DSL
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
// Apply the Kotlin JVM plugin to add support for Kotlin on the JVM.
id("org.jetbrains.kotlin.jvm").version("1.3.21")
id("com.github.johnrengelman.shadow") version "5.0.0"
// Apply the application plugin to add support for building a CLI application.
application
}
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
dependencies {
// Use the Kotlin JDK 8 standard library.
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// Use the Kotlin test library.
testImplementation("org.jetbrains.kotlin:kotlin-test")
// Use the Kotlin JUnit integration.
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
implementation("org.http4k:http4k-core:3.143.1")
implementation("org.http4k:http4k-server-jetty:3.143.1")
implementation("org.http4k:http4k-client-okhttp:3.143.1")
implementation("org.http4k:http4k-client-apache:3.143.1")
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
application {
// Define the main class for the application.
mainClassName = "com.benito.AppKt"
}
tasks.withType<ShadowJar> {
archiveBaseName.set("${project.name}-all")
}
Kotlin Code
import org.http4k.core.HttpHandler
import org.http4k.core.Method
import org.http4k.core.Request
import org.http4k.core.Response
import org.http4k.core.Status.Companion.OK
import org.http4k.routing.bind
import org.http4k.routing.path
import org.http4k.routing.routes
import org.http4k.server.Jetty
import org.http4k.server.asServer
fun main(args: Array<String>) {
println("Starting")
val app: HttpHandler = routes(
"/ping" bind Method.GET to { _: Request -> Response(OK).body("pong!") },
"/greet/{name}" bind Method.GET to { req: Request ->
val path: String? = req.path("name")
Response(OK).body("hello ${path ?: "anon!"}")
}
)
app.asServer(Jetty(8080)).start()
}
Error Message
2019-05-15 11:15:13.925:INFO::main: Logging initialized #287ms to org.eclipse.jetty.util.log.StdErrLog
2019-05-15 11:15:14.039:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2019-04-29T20:42:08.989Z; git: e1bc35120a6617ee3df052294e433f3a25ce7097; jvm 1.8.0_211-b12
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.eclipse.jetty.http.MimeTypes$Type.<init>(MimeTypes.java:103)
at org.eclipse.jetty.http.MimeTypes$Type.<clinit>(MimeTypes.java:58)
at org.eclipse.jetty.http.MimeTypes.<clinit>(MimeTypes.java:191)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:836)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:278)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
at org.eclipse.jetty.server.Server.start(Server.java:418)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.Server.doStart(Server.java:382)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.http4k.server.Jetty$toServer$3.start(jetty.kt:33)
at com.benito.AppKt.main(App.kt:38)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
at org.eclipse.jetty.http.PreEncodedHttpField.<clinit>(PreEncodedHttpField.java:70)
... 14 more
The problem here is that during the process of merging all the JARs in to one FatJAR, the contents of the META-INF folder in the http4k-core JAR (which contains the mime.types file used for matching a request to a content type) is somehow omitted or overridden by the merging process.
This isn't http4k specific and is (quite) a common problem with the use of the shadow-jar gradle plugin. But it can be easily solved by just correctly configuring the plugin as below:
shadowJar {
mergeServiceFiles() // <-- this!
}
From the http4k side, the exception message generated has been changed to highlight this problem.

#SpringBootTest - failed to load applicationcontext

Test class:
#RunWith(SpringRunner.class)
#SpringBootTest
public class FileInterfaceTest {
#Test
public void contextLoads() {
}
}
Application :
AppConfig:
#Configuration
#ImportResource({ "classpath:process-flows.xml" })
public class AppConfig {
}
Have Bootstraploader class.
Error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [file.properties] cannot be opened because it does not exist
Resources loaction:
src/main/resources
---process-flow.xml
--- process.yml
src/main/resources/env/cconfig
--- file.properties
Your folder structure contains a typo: src/main/resources/env/cconfig has to be src/main/resources/env/config
As defined in the Spring Externalized Configuration, SpringApplication loads properties from application.properties files in the following locations and adds them to the Spring Environment:
A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root
Apart from "cconfig" folder name (not sure if that was a typo) I also see your #ImportResource is mentioned as classpath:process-flows.xml however your resources folder has file named process-flow.xml
If that was not a typo as well, please add an 's' by renaming process-flow.xml to process-flows.xml and retry

Maven Dependency & Spring - Overwrite application context from dependency war

I manage to add dependency ProjectWeb project into SchedulerWeb project. Successful run the web that has been develop in ProjectWeb project through SchedulerWeb package.
However, i cannot inject bean in SchedulerWeb project. When I start instance of SchedulerWeb, it not scan SchedulerWeb annotation.
ProjectWeb
- src/main/java.....
- src/main/resource
- applicationContext.xml
- <context:component-scan base-package="com.myprojectWEB.service" />
SchedulerWeb
- src/main/java.../scheduler
- mainScheduler.java
- src/main/resource
- applicationContext.xml
- <context:component-scan base-package="com.myprojectWEB.service" />
- <context:component-scan base-package="com.myprojectWEB.scheduler" />
in com.myprojectWEB.scheduler i create one class and the code is per below.
#Configuration
#EnableScheduling
public class Main {
#Scheduled(fixedDelay = 500)
public void executeEveryOneMin() {
System.out.println("Run Job " + new Date());
}
}
So how i want the SchedulerWeb will call their own applicationcontext.xml?
** i put the scheduler in projectWEB is working fine but not in SchedulerWeb.
Any advice?

Arquillian can't find Wildfly - org.jboss.arquillian.container.spi.client.container.LifecycleException

I'm trying to run Arquillian tests on a Wildfly managed container.
Here's the Arquillian's deployment and the test:
#RunWith(Arquillian.class)
public abstract class ArquillianTestCase {
#Deployment
public static WebArchive createDeployment() {
/* Create the war file according to build.gradle. */
WebArchive war = ShrinkWrap.create(EmbeddedGradleImporter.class)
.forThisProjectDirectory().importBuildOutput()
.as(WebArchive.class);
/* Add the abstract test classes to war. */
war.addClasses(ArquillianTestCase.class, SeleniumTestCase.class);
/* Add selenium and its transitive dependencies to war's lib. */
String seleniumJava = "org.seleniumhq.selenium:selenium-java:3.3.1";
MavenResolverSystem resolver = Maven.resolver();
File[] seleniumFiles = resolver.resolve(seleniumJava).withTransitivity()
.asFile();
war.addAsLibraries(seleniumFiles);
return war;
}
}
public class LoginTest extends ArquillianTestCase {
#Test
public void shouldRun() throws Exception {
System.out.println("LoginTest!");
Assert.assertTrue(true);
}
}
I don't have any arquillian.xml file, so I rely on JBOSS_HOME environment variable to let Arquillian find my Wildfly:
echo $JBOSS_HOME
/opt/wildfly-8.2.1.Final
All of this process is started by a Gradle build, so here are the most relevant dependencies of my build.gradle file:
dependencies {
/* Arquillian for managing the life cycle of the container. */
testCompile 'org.jboss.arquillian.junit:arquillian-junit-container:1.1.10.Final'
/* Arquillian and Wildfly integration. */
testCompile 'org.wildfly:wildfly-arquillian-container-managed:8.2.1.Final'
/* Arquillian and Gradle integration. */
testCompile 'org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-gradle-depchain:2.2.6'
/* Arquillian and Maven integration for resolving dependencies at runtime. */
testCompile 'org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-api-maven:2.2.6'
testCompile 'org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven:2.2.6'
/* Selenium for front-end testing. */
testCompile 'org.seleniumhq.selenium:selenium-java:3.3.1'
}
If I run this setup on Windows with my JBOSS_HOME pointing to a valid Wildfly installation, it works fine, but when I reproduce the same setup on Ubuntu Server 14.04, I get the error below:
org.jboss.arquillian.container.spi.client.container.LifecycleException: Could not start container
at org.jboss.as.arquillian.container.managed.ManagedDeployableContainer.startInternal(ManagedDeployableContainer.java:208)
at org.jboss.as.arquillian.container.CommonDeployableContainer.start(CommonDeployableContainer.java:112)
at org.jboss.arquillian.container.impl.ContainerImpl.start(ContainerImpl.java:199)
at org.jboss.arquillian.container.impl.client.container.ContainerLifecycleController$8.perform(ContainerLifecycleController.java:163)
at org.jboss.arquillian.container.impl.client.container.ContainerLifecycleController$8.perform(ContainerLifecycleController.java:157)
at org.jboss.arquillian.container.impl.client.container.ContainerLifecycleController.forContainer(ContainerLifecycleController.java:255)
at org.jboss.arquillian.container.impl.client.container.ContainerLifecycleController.startContainer(ContainerLifecycleController.java:156)
(omitted dozens of lines to improve readability)
Caused by: java.lang.NullPointerException
at java.io.File.<init>(File.java:277)
at org.jboss.as.arquillian.container.managed.ManagedDeployableContainer.startInternal(ManagedDeployableContainer.java:94)
... 84 more
I tried to reproduce this behavior on Windows and realised that it happens when I remove my environment variable JBOSS_HOME, so Arquillian doesn't find my container, but back on Ubuntu, even that variable exists, it doesn't work.
Any ideas? Thanks in advance.

Resources