find path to JAX-RS resource - maven

I just can't find out the path to access my JAX-RS resource which is deployed to wildfly.
ear.ear pom:
<parent>
<artifactId>jee-services</artifactId>
<groupId>org.mycompany</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<packaging>ear</packaging>
<modelVersion>4.0.0</modelVersion>
<artifactId>ear</artifactId>
<dependencies>
<dependency>
<groupId>org.mycompany</groupId>
<artifactId>ejb_book</artifactId>
<version>1.0-SNAPSHOT</version>
<type>ejb</type>
</dependency>
</dependencies>
ejb_book pom:
<parent>
<artifactId>jee-services</artifactId>
<groupId>org.mycompany</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>ejb</packaging>
<artifactId>ejb_book</artifactId>
application config
#ApplicationPath("/resources")
public class ApplicationConfig extends Application {
}
resource
#Stateless
#Path("/books")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public class BookResource extends AbstractFacade<Book> {
#PersistenceContext
private EntityManager entityManager;
#GET
#Path("/getBooks")
public Book getBook() {
return new Book();
}
I think the issue is that I'm packaging my ejb_book.jar into ear.ear (where I collect all other ejb-modules)
I tried:
localhost:8080/ear/resources/books/getBooks
and many other combinations but none of them worked.
The application deploys fine to the WildFly server.
BTW: is there a tool to help people access their JAX-RS resource? From the IDE for example. So my question wouldn't be a problem anymore.

According to the JAX-RS 2.0 specification, section 2.3.2 Servlet
A JAX-RS application is packaged as a Web application in a .war file.
Since you're not packaging your application as a WAR module and neither you have a WAR module in your EAR, you're not providing a context-root to your (web) application.
This is preventing you from accessing your REST API through the desired way:
http://localhost:8080/<context-root>/resources/books/getBooks
As a solution, you could either package your entire application as a WAR, placing the application classes in WEB-INF/classes or WEB-INF/lib and required libraries in WEB-INF/lib, or you could maintain the use your EAR, adding to it a WAR module.

Related

Is there any alternatives to registerColumnType on upgrade from Hibernate-core:5.6.10.Final to 6.1.5.Final

I am currently upgrading from Spring-boot-starter-parent 2.7.3 to 3.0.0. The hibernate-core dependency for this is 6.1.5.Final.
This has broken my custom SQL dialect I had implemented.
The server dialect class is below:
public class ServerDialect extends SQLServer2012Dialect {
public ServerDialect() {
super();
registerColumnType(Types.NVARCHAR, "nvarchar(max)");
registerHibernateType(Types.NVARCHAR, StandardBasicTypes.STRING.getName());
}
}
Since upgrade, these method's can no longer be resolved.
All I have changed is:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
to
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
I have looked up the documentation and searched for alternatives with no success.
It might be worth evaluating if this Dialect is required for your project post upgrade - prior to Hibernate 6 it was common to provide the Dialect version via the hibernate.dialect setting, but it is no longer the recommended strategy. More information on this can be found in the documentation.
If this is not a suitable resolution, there is however a workaround for your issue.
SQLServer2012Dialect is now deprecated so as part of this migration should should consider refactoring your custom dialect to use the recommended SQLServerDialect.
You should be able to make use of resolveSqlTypeDescriptor to achieve the same or similar functionality - for example;
#Override
public JdbcType resolveSqlTypeDescriptor(String columnTypeName,
int jdbcTypeCode,
int precision,
int scale,
JdbcTypeRegistry jdbcTypeRegistry) {
switch (jdbcTypeCode) {
case Types. NVARCHAR, Types.CHAR -> jdbcTypeCode = StandardBasicTypes.STRING.getSqlTypeCode();
// ETC
}
return super.resolveSqlTypeDescriptor(
columnTypeName,
jdbcTypeCode,
precision,
scale,
jdbcTypeRegistry
);
}
However, given your example above - this should not be required as the newer Hibernate should automatically perform an NVARCHAR mapping like this for you.

How do I fix HTTP Status 404 - Not Found on Intellij IDEA?

I've started my first job 2 months ago and it's been awhile since I've dealt with Spring. I'm trying to run Tomcat server, and display "/home" but I'm getting 404 on it. When I hover at my "home", IntelliJ IDEA is showing home.html . Error
HTTP Status 404 – Not Found
Type Status Report
Message The requested resource [/home] is not available
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Apache Tomcat/9.0.65
HTTP error
Code folders screenshot
Tomcat config
Tomcat deployment config
I've googled about it but it's doesn't fix it. Here is my code.
File HomeController.java
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class HomeController {
#RequestMapping("/home")
public String landingPage() {
return ("home");
}
}
File home.html
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Landing page</h1>
</body>
</html>
File pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>demo</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
I also tried to run my older projects that works but now it doesn't.
Thank you in advance!
try to use ModelAndView:
#RequestMapping("/")
public ModelAndView index () {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("home");
return modelAndView;
}
You are using Spring Boot, which has an embedded Tomcat server. I believe you have a standalone Tomcat running on port 8080 on your machine, preventing Spring Boot from using its own embedded Tomcat.
Stop the standalone Tomcat and start the Spring Boot application again.
Everything looks good. Spring boot doesn't require you to do any tomcat configuration.
The configuration you have should be the problem. Re create the project without the Tom Cat config and deployment config.
Check out this video: https://www.youtube.com/watch?v=HYGnVeCs0Yg&t=4235s
As previous answers mentioned before, you're using Spring Boot, which has its embedded Tomcat server under the hood. It's the default behavior, but you may configure your Spring Boot project to use Netty or Undertow servers, please check more details here — Embedded Web Servers
So since you already have the Tomcat server, there is no need to configure it in your IDE. Also, worth mentioning that running a project from your IDE is not the best idea. Especially, when you're describing your steps for reproducing the issue to someone else. Instead, you may run your Spring Boot project from the command line using the such command:
mvn spring-boot:run
By default, it'll start your application on the 8080 port and you will be able to access your homepage at this URL: localhost:8080/home
For more details on running your Spring Boot application, you may check this document — Running your application
To run the Spring Boot project from your IntelliJ IDEA, you need to open the DemoApplication class (in your case), which has the main method. And on the left, there should be a play button for running your project. You can also configure it in the 'Edit configurations' menu by selecting the 'Spring Boot' item under the 'Add new configuration' menu.
Updated:
I'm using that you're using macOS. To identify the process running on the 8080 port, which prevents you from starting your Spring Boot application, you may use such command:
sudo lsof -i :8080
This is the example output of this command from my machine, which has the Docker container running on the 8080 port:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
com.docke 3134 golovnya 174u IPv6 0xcaf3b5f3fb45111 0t0 TCP *:http-alt (LISTEN)
Here we're interested in PID, which stands for the process identifier. It's a unique id of the running application. In my case, the PID of the process running on the 8080 port is 3134. Knowing this, we may kill this process by the following command:
kill -9 <PID>
In my case it will look like this:
kill -9 3134
That's all.
P.S. If it looks a bit complicated to your or you experience some issues, reloading your machine is always not a bad idea.

display application version in title using thymeleaf and springboot

I want to display in my htm page the version of my webapp, using something like this (thymeleaf inside) :
<h4 th:text="${version}">Version</h4>
The data is well set in the pom.xml :
<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>fr.test.navig</groupId>
<artifactId>navigo</artifactId>
<version>2.0.3-SNAPSHOT</version>
...
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>Application</mainClass>
<addDefaultImplementationEntries>
true
</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
and I can see it in the MANIFEST.MF (which is in the generated jar under META-INF) :
Implementation-Version: 2.0.3-SNAPSHOT
I've tried to get the appplication version in the controller and set it in a ModuleAttribute :
#ModelAttribute("version")
public String getVersion() {
logger.info("ModelAttribute to get application version");
return getClass().getPackage().getImplementationVersion();
}
But getClass().getPackage().getImplementationVersion() value is null. Indeed the package implementationVersion is not the implementation Version of the application by default.
I know I'm late but Patrick's answer and Spring docs greatly helps in this matter.
1. If your pom.xml use spring-boot-starter-parent as parent, you can use #project.version# to get version (and any other Maven properties) in your application.properties file. According to Spring docs:
You can automatically expand properties from the Maven project using
resource filtering. If you use the spring-boot-starter-parent you
can
then refer to your Maven ‘project properties’ via #..# placeholders
Maven pom.xml:
<groupId>com.foo</groupId>
<artifactId>bar</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Foo</name>
<description>Bar</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
Spring application.properties:
foo.app.version=#project.version#
2. Then a class annotated with #ControllerAdvice can be used to inject version as model attribute.
#ControllerAdvice
public class ControllerAdvice {
#Value("${foo.app.version}")
private String applicationVersion;
#ModelAttribute("applicationVersion")
public String getApplicationVersion() {
return applicationVersion;
}
}
3. Finally this model attribute can be accessed by Thymeleaf as any other.
<th:block th:text="${applicationVersion}"></th:block>
Hope this helps!
Here is the simplest way I've found :
In my controller :
#ModelAttribute("version")
public String getVersion() throws IOException {
logger.info("ModelAttribute to get application version");
Manifest manif = new Manifest(
Application.class.getResourceAsStream("/META-INF/MANIFEST.MF"));
String version = (String) manif.getMainAttributes().get(
Attributes.Name.IMPLEMENTATION_VERSION);
return version;
}
In my htm page :
<h4 th:text="${version}">Version</h4>
You need to configure resource plugin to activate filtering on the file that need to be enriched with properties coming from your POM file.
In the generated war, the version (in fact ${project.version}) will be hardcoded to your POM version.

NullPointerExpection on basic EJB application in NetBeans 7.3.1

I'm doing a course on Enterprise computing using Beginning Java EE 6 Platform with GlassFish 3: From Novice to Professional
Last chapter was about EJB and I've actually found it very hard to understand.
I've been trying to run one of the book's sample codes in order to try to better understand EJB but I'm getting a NullPointerException whenever I call for the EJB.
I'm using NetBeans 7.3.1 and the Maven and Glassfish versions provided with NetBeans (Maven seems to be 3.0.5, and Glassfish is 4.0)
This is the code for the main class:
package org.beginningee6.book.chapter06;
import javax.ejb.EJB;
/**
* #author Antonio Goncalves
* APress Book - Beginning Java EE 6 with Glassfish
* --
*/
public class Main {
// ======================================
// = Attributes =
// ======================================
#EJB
private static BookEJBRemote bookEJB;
// ======================================
// = Public Methods =
// ======================================
public static void main(String[] args) {
// Creates an instance of book
Book book = new Book();
book.setTitle("The Hitchhiker's Guide to the Galaxy");
book.setPrice(12.5F);
book.setDescription("Science fiction comedy series created by Douglas Adams.");
book.setIsbn("1-84023-742-2");
book.setNbOfPage(354);
book.setIllustrations(false);
book = bookEJB.createBook(book);
System.out.println("### Book created : " + book);
book.setTitle("H2G2");
book = bookEJB.updateBook(book);
System.out.println("### Book updated : " + book);
System.out.println("Execution succeeded");
}
}
Here is the persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="chapter06PU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<!--<jta-data-source>jdbc/__default</jta-data-source>-->
<jta-data-source>jdbc/chapter06DS</jta-data-source>
<class>org.beginningee6.book.chapter06.Book</class>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.logging.level" value="INFO"/>
</properties>
</persistence-unit>
</persistence>
And this is the pom.xml:
<?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>org.beginningee6.book</groupId>
<artifactId>chapter06</artifactId>
<packaging>jar</packaging>
<version>2.0</version>
<name>Week5</name>
<parent>
<groupId>org.beginningee6.book</groupId>
<artifactId>chapters</artifactId>
<version>2.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>${javax.persistence-version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>${eclipselink-version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>${glassfish-version}</version>
</dependency>
</dependencies>
<!--To avoid multiple modules with Maven, here is what you need to manually do (it's not nice, but it works)
1) Comment the following section (maven-jar-plugin), package the jar, and deploy to GlassFish
2) Uncomment the following section, package the jar and run the Main class with app client -->
<build>
<!-- <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${plugin-jar-version}</version>
<configuration>
<archive>
<manifest>
<mainClass>org.beginningee6.book.chapter06.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>-->
</build>
</project>
I'm getting this error:
Exception in thread "main" java.lang.NullPointerException
at this line:
book = bookEJB.updateBook(book);
Apparently Maven is giving this error:
Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec (default-cli) on project chapter06: Command execution failed. Process exited with an error: 1 (Exit value: 1) -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.2.1:exec (default-cli) on project chapter06: Command execution failed.
And after activating Maven's debugging option the last command line before the error is:
Executing command line: C:\Program Files (x86)\Java\jdk1.7.0_21\bin\java.exe -classpath C:\Users\Manuel_Laptop\Desktop\Week5\COIT20227LabSolWeek5\Week5\target\classes;C:\Users\Manuel_Laptop\.m2\repository\org\eclipse\persistence\javax.persistence\2.0.0\javax.persistence-2.0.0.jar;C:\Users\Manuel_Laptop\.m2\repository\org\eclipse\persistence\eclipselink\2.0.1\eclipselink-2.0.1.jar;C:\Users\Manuel_Laptop\.m2\repository\org\glassfish\extras\glassfish-embedded-all\3.0.1-b19\glassfish-embedded-all-3.0.1-b19.jar org.beginningee6.book.chapter06.Main
After going through some course tips and some forums I went and set my JAVA_HOME and M2_HOME to their respective directories but nothing worked. I even found a link to someone having an issue on the same chapter of the textbook (https://getsatisfaction.com/javaee6/topics/yet_another_chapter_6_ejb_problem) after seeing it referenced here in StackOverflow, but couldn't find anything there (didn't understand it to be honest)
It's not maven issue, you should set up ejb container in java SE enviroment to use EJB.
Try someithing like this
EJBContainer.createEJBContainer()
you can get complete example at http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/embeddedContainerDemo/EmbeddedContainerDemo.html

Maven, multi web modules shared Controllers, jsp, styles, scripts

It's it possible with Maven to share common controllers, jsp's and other resources to the web module.
Structure
web1 (packaging jar)
--main
--java
--controller
MyControllerToShared with #Controller annotation
--resources
--webapp
--scripts
javascripts files
--styles
css files
--WEB-INF
--views
jsp to share
pom.xml
web2 (packaging war)
Classic web app structure with dependency of web1.jar
My web2 app works but no mapping found for HTTP request with URI define in web1 module. I use annotation #Controller and #RequestMapping. I defined in the servlet.xml:
<context:component-scan base-package="controller" />
<mvc:annotation-driven/>
How can I share controllers and resources between different web modules?
At the end, I need to have 3 web app with commons stuffs (error handler, jsp's errors, styles, js, ...).
Why don't you just create an extra project with all the shared resources? You can reuse that in all your web apps, just include the shared file in your pom.xml as a dependency.
You can start with an additional project with the shared resources:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nl.connexys</groupId>
<artifactId>shared</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Shared resources</name>
</project>
In your webapp project you can then use that project as a dependency:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nl.connexys</groupId>
<artifactId>webapp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Webservice endpoints</name>
<dependencies>
<dependency>
<groupId>nl.connexys</groupId>
<artifactId>shared</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
But this is all very basic Maven stuff. I think the examples should point you in the right direction.
Take a look at this answer:
https://stackoverflow.com/a/14143954/600007
, and the refernce for that: http://maven.apache.org/plugins/maven-war-plugin/overlays.html
It will work for jsp-s, js-s, etc...

Resources