I am trying to create a spring boot app with jsf and gradle.
So far, during development everything was fine. When I wanted to run my App I just typed gradle bootRun, the app started and I was able to access it under 'localhost'.
Now I am at a point of time, where I want to deploy the app, therefore I run the command 'gradle clean distTar' which creates the tar file to deploy.
After running the generated script and accessing my app via Browser I just get an 404 with the message.
index.xhtml Not Found in ExternalContext as a Resource
Also in the jar file, there aren't any html files included. I included them in the jar with the command
from ("${projectDir}/src/main/webapp/"){
into('resources')
}
Referring to https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot
this files should be accessible. But still nothing changed.
Does anyone else have a clue? What am I doing wrong?
BR
I've been also struggling with this thing and finally managed to come up with a working solution.
As stated in: https://stackoverflow.com/a/9473487/4250114 if you use Servlet3.x (and you probably are with SpringBoot).
For me structure in maven looks like below worked:
src
|-main
| ...
|-resources
|-META-INF
|-faces-config.xml
|-resources
|-test.xhtml
So in jar it should be:
|-META-INF
|-faces-config.xml
|-resources
|-test.xhtml
Follow the given structure to create fat jar :
Demo
└── src
| ├── main
| │ ├── java
| │ │ └── org
| │ │ └── demo
| │ │ └── App.java
| │ └── resources
| | |
| │ └── application.properties
| | |
| | └── META-INF
| | | └── resources
| | | └── jsp
| | └── static
| | └── css
| | └── js
| |
| └── test
| └── java
| └── org
| └── demo
| └── App.java
├──── pom.xml
Based on information from https://github.com/spring-projects/spring-boot/issues/8299 and also based on the output from SpringBoot+Jetty
2018-01-15 15:57:03 [main] INFO o.j.jetty.JsfJettyServerCustomizer - Setting Jetty classLoader to META-INF/resources directory
I used this in my Gradle file:
jar {
baseName = 'csm'
version = "0.0.1-SNAPSHOT"
from("build/docs/"){
into("generated/docs/")
}
from("src/main/resources/"){
include("**")
}
// JSF and SpringBoot and Jetty require all webapp files to be in a very particular location.
// See: https://github.com/spring-projects/spring-boot/issues/8299
from ("${projectDir}/src/main/webapp/"){
into('META-INF/resources')
}
}
/BOOT-INF
/META-INF/
/resources/
/WEB-INF/
web.xml
index.jsf
blah.xhtml
Related
I have a JavaFX project with Gradle built tool. What is the right way to construct the src/main/resources folder so that I could easily access the *.fxml and *.css by simple line of code:
Parent root = FXMLLoader.load(getClass().getResource("xxx.fxml"));
I'm using the Gradle plugin and build.gradle file for JavaFX in this tutorial, It has a simple project tree like this:
.
├── src.main
| ├── java
| | ├── org.openjfx
| | | ├── MainApp.java
| | └── └── FXMLController.java
| ├── resources
| | ├── org.openjfx
| | | ├── scene.fxml
└── └── └── └── styles.css
In this way, the MainApp.java can load scene.fxml using getResource("scene.fxml").
However, if the java and the resources directory structures doesn't match, suppose my project tree like this so that I could separate the fxml file and css file:
.
├── src.main
| ├── java
| | ├── org.openjfx
| | | ├── anotherPackage
| | | | ├── MainApp.java
| | └── └── FXMLController.java
| ├── resources
| | ├── org.openjfx
| | | ├── layouts
| | | | ├── scene.fxml
| | | ├── styles
└── └── └── └── └──styles.css
Now the MainApp.java have to load scene.fxml with getResource("../layouts/scene.fxml")
I am new to Gradle and JavaFX, and I want to know what is the right way to manage the resources including fxml, CSS, as well as pictures, etc.
ps. Sorry if I'm not asking the question correctly.
iirc, the resource directory structure should mirror the package structure. take a look at https://www.eviltester.com/2017/12/resource-files-for-tests-java-maven.html
When setting the debug configurations for the default IntelliJ IDEA Java helloworld application (created upon making a new AWS Lambda project) the following response is shown:
Error: Cannot find handler 'helloworld.App::handleRequest' in project."
To fix this I've tried editing 'Handler' element inside template.yaml to include a filepath, though there had been no success.
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::handleRequest
I noticed the Python AWS Lambda helloworld project (within the PyCharm counterpart) required me to change the root project folder (allowing the handler to be found), however, I cant seem to achieve this with the Java counterpart within IntelliJ.
The default project file structure is as follows:
bash
├── README.mdH
├── HelloWorldFunction
│ ├── pom.xml
│ └── src
│ ├── main
│ │ └── java
│ │ └── helloworld
│ │ ├── App.java
│ │ └── GatewayResponse.java
│ └── test
│ └── java
│ └── helloworld
│ └── AppTest.java
└── template.yaml
The relevant section of the template.yaml file contains:
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: HelloWorldFunction
Handler: helloworld.App::handleRequest
Runtime: java8
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
The App.java file contains the class
public class App implements RequestHandler<Object, Object> {
...
}
I would like the debug configuration to point to the correct Handler ( being "helloworld.App::handleRequest") so I can run the project on my local machine.
On project files, right click on HelloWorldFunction then find Mark directory as and choose Source Root. That should fix your problems.
Trying to run Java-based (compiled) migration files which are not in the project where Flyway is configured. Can anyone tell me is it possible to do so?
I've created a jar which use flyway to do migrations. Jar expects an argument which is migration scripts' location. Migration scripts are in a different location/project. So far all scripts are SQL based. (i.e. XXX.sql). Need to add a java based migration scripts to it, to do some complex logic.
Tried to add pom.xml to the script location and a sample java migration script in db/migration folder. Java-based migration file is ignored by Flyway. Is it due to checksum validation fail?
Java-based migrations are compiled and .class files are in the classpath. My folder structure as below.
C:/
└── database-migration-scripts
└── src/main/java/
└── db
└── migration
└── V1__m1.sql
└── V2__m2.sql
└── V3__SampleJava_script.java
└── target/classes/
└── db
└── migration
└── V3__SampleJava_script.class
└── pom.xml
W:/
└── someLocationOutsideProject
└── flyway-database-migration.jar
NOTE: flyway runner (jar) and scripts will be in different locations in the same or different machine. In the example above, migration scripts in C:/ and jar in W:/
In order to be discovered, Java migrations should go under src/main/java with the package db.migration
e.g.
package db.migration; // <-- classpath:db/migration
import org.flywaydb.core.api.migration.jdbc.JdbcMigration;
import java.sql.Connection;
public class V3__SampleJava_script implements JdbcMigration {
public void migrate(Connection connection) throws Exception {
// your code...
}
}
Difficult to diagnose without seeing your pom.xml and how your jar is packaged but given the folder structure of your target directory above, perhaps either the V3__SampleJava_script.class is added to the jar under classpath:resources/db/migration or is just not included at all.
To check, try unzipping the jar file:
jar -xf flyway-database-migration.jar
or just listing the contents:
jar -tf flyway-database-migration.jar
It is also worth noting that if you have overridden the locations setting with a filesystem: path, the documentation states that the directory "may only contain sql migrations", any java migrations will just be ignored.
Update 2018-06-03
Given that the flyway-database-migration.jar is being pointed to a filesystem: location, only sql migrations will be discovered, not java ones. The database-migration-scripts directory needs to be added to the classpath and the flyway location set to classpath:db/migration.
java -cp C:\database-migration-scripts;<existing classpath> ...
Update 2018-06-09
Because of the way that the flyway-database-migrations.jar is packaged, using the Spring Boot Executable Jar format, all the application dependencies are placed in the BOOT-INF/lib directory inside the executable jar and are loaded by a separate classloader from the org.springframework.boot.loader.JarLauncher main class. So, contrary to the above, I'm not sure if it's possible to pass additional classpath entries to the application using the -cp command line option. I think you would need to remove spring boot and package it as a regular jar file. I certainly encountered class visibility issues and decided to try a different approach.
I downloaded the Flyway Command Line Runner and updated the <RUNNER_DIR>/conf/flyway.conf settings with the following:
flyway.url=jdbc:mariadb://localhost:3306/flyway?createDatabaseIfNotExist=true
flyway.user=root
flyway.password=yourPassword
flyway.locations=classpath:db/migration
I created a directory under <RUNNER_DIR>/jars/ called database-migration-scripts.jar with the following structure (the .jar is important as Flyway will only add files or directories with this suffix to the classpath):
database-migration-scripts.jar/
└── db
└── migration
├── V1__m1.sql
├── V2__m2.sql
└── V3__SampleJava_script.class
Finally, I added all of the runtime dependencies for the database-migration-scripts project to <RUNNER_DIR>/lib:
lib/
├── animal-sniffer-annotations-1.14.jar
├── checker-compat-qual-2.0.0.jar
├── checker-qual-2.3.0.jar
├── error_prone_annotations-2.1.3.jar
├── flyway-commandline-5.1.1.jar
├── flyway-core-5.1.1.jar
├── guava-23.6-jre.jar
├── j2objc-annotations-1.1.jar
├── jcl-over-slf4j-1.7.25.jar
├── jsr305-1.3.9.jar
├── jul-to-slf4j-1.7.25.jar
├── log4j-over-slf4j-1.7.25.jar
├── logback-classic-1.1.11.jar
├── logback-core-1.1.11.jar
├── slf4j-api-1.7.25.jar
├── snakeyaml-1.17.jar
├── spring-aop-4.3.13.RELEASE.jar
├── spring-beans-4.3.13.RELEASE.jar
├── spring-boot-1.5.9.RELEASE.jar
├── spring-boot-autoconfigure-1.5.9.RELEASE.jar
├── spring-boot-starter-1.5.9.RELEASE.jar
├── spring-boot-starter-jdbc-1.5.9.RELEASE.jar
├── spring-boot-starter-logging-1.5.9.RELEASE.jar
├── spring-context-4.3.13.RELEASE.jar
├── spring-core-4.3.13.RELEASE.jar
├── spring-expression-4.3.13.RELEASE.jar
├── spring-jdbc-4.3.13.RELEASE.jar
├── spring-tx-4.3.13.RELEASE.jar
├── tomcat-jdbc-8.5.23.jar
└── tomcat-juli-8.5.23.jar
After that I was able to successfully run:
./flyway migrate
And was able to verify that both sql and java migrations had been successfully applied:
./flyway info
+-----------+---------+-------------------+-------------+---------------------+---------+
| Category | Version | Description | Type | Installed On | State |
+-----------+---------+-------------------+-------------+---------------------+---------+
| Versioned | 1 | m1 | SQL | 2018-06-09 07:41:57 | Success |
| Versioned | 2 | m2 | SQL | 2018-06-09 07:41:57 | Success |
| Versioned | 3 | SampleJava script | SPRING_JDBC | 2018-06-09 07:47:56 | Success |
+-----------+---------+-------------------+-------------+---------------------+---------+
Phew! This is much harder work than packaging the migrations with the application, in my opinion.
One of the other downsides of this approach is that if someone adds a new java migration with an additional dependency (e.g. commons-lang3, or whatever else) that dependency needs to be added to the <RUNNER_DIR>/lib directory as well.
Hope this helps!
I have a gradle-based java project with this structure
.
├── myproject
│ ├── src
│ | └── main
│ | ├── java
│ | └── resources
│ | └── myresource.xml
| ├── build
| | ├── classes
| | | └── main
│ | | └── myresource.xml
| | ├── resources
I'm trying to access some files in the resources folder using a ClassLoader, like this
ClassLoader.getSystemClassLoader().getResoure("/myresource.xml");
but it does not find the file.
The only way I have found to access those files is by exploring the known structure of the project
Path resourcesPath= FileSystems.getDefault().getPath(System.getProperty("user.dir"), "/src/main/resources/");
Any idea on what am I doing wrong?
Well, it seems my difficulties came from another problem (resources not being copied to the proper places). Once I solved that problem, the ClassLoader was able to find my resources using either of these two forms:
ClassLoader.getSystemClassLoader().getResource("./myresource.xml");
ClassLoader.getSystemClassLoader().getResource("myresource.xml");
Edit: When using the jar embedded in other applications, the former solution do not work, use this in that case:
Thread.currentThread().getContextClassLoader().getResource("myresource.xml")
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource(java.lang.String)
For example something like MyMain.class.getResource("/config.txt") or use relative path when appropriate.
Maybe you should use it this way:
Thread.currentThread().getContextClassLoader().getResource("myresource.xml")
If i use ClassLoader.getSystemClassLoader().getResource("myresource.xml")
When I use it as a jar package embedded in other applications, I still have no access to resources.
Another solution to access Java resources in the build.gradle with in Gradle in Groovy is to do for example to read VERSION file in the Java resources:
static String getVersion(File rootFile) {
File versionFile = new File(rootFile, "src/main/resources/VERSION")
byte[] versionBytes = Files.readAllBytes(versionFile.toPath())
String version = new String(versionBytes, StandardCharsets.UTF_8).trim()
version
}
version = getVersion(project.projectDir)
It avoids manipulating the ClassLoader.
Note: sourceSets.main.output.resourcesDir does not exist yet in function of the task.
I need javascript i18n in my web application which is based on Spring MVC.
For javascript 18n I am using jQuery.i18n.properties and the URL where I found it is http://code.google.com/p/jquery-i18n-properties/
When I run a sample application, it works properly but when I integrate it in my application it does not work.
Basically my javascript code is not able to load the js properties files. When I show a alert using keys, it always shows key but not the key values.
Here is my project structure.
└── WebRoot
├── resources
│ └── scripts
│ ├── i18n
├ ├── resourceBundles
├ ├ ├── Messages_en
├ ├ ├── Messages_fr
├ ├── jquery.i18n
├ ├── jquery.i18n.properties
├──jquery-1.4.min
├──jquery-ui-1.8.2.custom.min
└── WEB-INF
├── spring
│ ├── app
│ │ ├── controllers.xml
│ │ └── servlet-context.xml
├── jsp
│ ├── home.jsp
│
└── web.xml
I have a resources folder where I have a scripts folder where I have my jquery js files. scripts folder also has a i18n folder where I have my i18n js files. i18n folder also has resource bundles folder where I have en and fr messages files.
In web inf I have a jsp folder which has my home jsp file. It has following code
jQuery(document).ready(function() {
loadBundles('en');
});
function loadBundles(lang) {
jQuery.i18n.properties({
name:'resources/scripts/i18n/resourceBundles/Messages',
mode:'both',
language:lang
});
}
Please help.
Try adding mime-type to the web.xml file (Tested in Tomcat 6)
<mime-mapping>
<extension>properties</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
Try by adding the path :-
name:'Messages',
path:'resources/scripts/i18n/resourceBundles/',
mode:'both',
language:'en'