2
votes

I started to play with JavaEE stuff, especially RESTEasy and I try to put together an small service packaged by maven. The service is done, ear package is created and deployed to a WildFly 10 server. No errors, but I'm not able to reach/call the service method.

I went through a lot of questions and answers here and according to them my app should work and I should be able to call it. One thing I don't know and haven't found any documentation so far how the url to reach the application is created.

The main question here: what are the rules of this url creation? Where can I find it?

So far, I have seen the following parameters can affect the url:

  • war file name (which one, the original (ends with SNAPSHOT string, or the finalName parameter defined in the rest project's pom.xml or the bundleFileName in ear package's pom.xml? Does thi war file name matters if war file is packaged into an ear?)
  • context root value defined in pom.xml of ear project (it is copied to application.xml file)
  • @ApplicationPath annotation over the Application class of RestEasy
  • web.xml if there is any
  • @Path values over the service classes and methods

Let's see my application.

My app consist of 3 maven module. There is the main module (pom module) having two modules, a, ear package module, b, rest api module creates war file. Pom.xml files are below.

Maven modules:

  • The pom module doesn't do anything.
  • The ear module puts together the ear file, and importantly it renames the war file to MasterData.Rest.Api.war.
  • The rest api web module produces a war file.

Eventually, the ear file looks like this:

  • Masterdata.Dataservice.ear
  • Masterdata.Dataservice.ear/MasterData.Rest.Api.war

No web.xml file, and no jboss.xml file.

According to a few articles and example the Currency/Currencies method should be available using the following urls (neither of them working):

Just simply deploying the war file doesn't work too. By default the file has this ugly name: digitallibrary.dataservice.masterdata.rest.api-1.0-SNAPSHOT.war. After successful deployment the endpoint should be available here:

It doesn't work.

Wildfly says the following and it can mean that the application can be accessed via the following urls (I'm just guessing...), but neither of them working...

Wildfly's deployment log.

19:58:17,673 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-5) WFLYSRV0027: Starting deployment of "MasterData.Dataservice.ear" (runtime-name: "MasterData.Dataservice.ear")
19:58:17,682 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-4) WFLYSRV0207: Starting subdeployment (runtime-name: "MasterData.Rest.Api.war")
19:58:17,712 INFO  [org.wildfly.extension.undertow] (ServerService Thread Pool -- 111) WFLYUT0021: Registered web context: /
19:58:17,727 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) WFLYSRV0010: Deployed "MasterData.Dataservice.ear" (runtime-name : "MasterData.Dataservice.ear")

Server is running and no errors.

package app;

import endpoints.CurrencyEndpoint;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

/**
 * Created by SayusiAndo on 6/9/2017.
 */
public class MasterDataRestEndpointApplication extends Application {

    private Set<Object> singletons = new HashSet<Object>();

    public MasterDataRestEndpointApplication() {
        singletons.add(new CurrencyEndpoint());
    }

    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>();
        return set;
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

package endpoints;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.ArrayList;

/**
 * Created by SayusiAndo on 6/9/2017.
 */
@Path("/currency")
public class CurrencyEndpoint {

    @GET
    @Path("/currencies")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getCurrencies() {
        ArrayList list = new ArrayList<String>();
        list.add("currency1");
        list.add("currency2");

        return Response
                .status(Response.Status.OK)
                .entity(list)
                .build();
    }
}

POM module 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>com.sayusiando</groupId>
    <artifactId>digitallibrary.dataservice.masterdata</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>digitallibrary.dataservice.masterdata.rest.api</module>
        <module>digitallibrary.dataservice.masterdata.package.ear</module>
    </modules>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.wildfly.plugins</groupId>
                <artifactId>wildfly-maven-plugin</artifactId>
                <version>1.2.0.Alpha4</version>
            </plugin>
        </plugins>
    </build>

</project>

EAR module 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">
    <parent>
        <artifactId>digitallibrary.dataservice.masterdata</artifactId>
        <groupId>com.sayusiando</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>ear</packaging>

    <artifactId>digitallibrary.dataservice.masterdata.package.ear</artifactId>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ear-plugin</artifactId>
                <version>2.10.1</version>
                <configuration>
                    <finalName>MasterData.Dataservice</finalName>
                    <modules>
                        <webModule>
                            <groupId>com.sayusiando</groupId>
                            <artifactId>digitallibrary.dataservice.masterdata.rest.api</artifactId>
                            <bundleFileName>MasterData.Rest.Api.war</bundleFileName>
                            <contextRoot>/</contextRoot>
                        </webModule>
                    </modules>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>com.sayusiando</groupId>
            <artifactId>digitallibrary.dataservice.masterdata.rest.api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>war</type>
        </dependency>
    </dependencies>


</project>

REST module 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">
    <parent>
        <artifactId>digitallibrary.dataservice.masterdata</artifactId>
        <groupId>com.sayusiando</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>war</packaging>
    <artifactId>digitallibrary.dataservice.masterdata.rest.api</artifactId>

    <dependencies>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.1-m07</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-servlet-initializer</artifactId>
            <version>3.1.2.Final</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>3.1.2.Final</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxb-provider</artifactId>
            <version>3.1.2.Final</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Generated application.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE application PUBLIC
    "-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
    "http://java.sun.com/dtd/application_1_3.dtd">
<application>
  <display-name>digitallibrary.dataservice.masterdata.package.ear</display-name>
  <module>
    <web>
      <web-uri>MasterData.Rest.Api.war</web-uri>
      <context-root>/</context-root>
    </web>
  </module>
</application>
1
what is your web.xml look like?Minh Kieu
There is no web.xml. The RestEasy documentation says that it is not needed.AndrasCsanyi
Expand your war and look inside. It may have auto-generated one? There must be a Class which wires up your Rest endpoints. It should be part of your .war as the endpoints need to serve by a HTTP Servlet.Minh Kieu
There were no web.xml, so I added one, an empty one. No changes.AndrasCsanyi
Look at this documentation docs.jboss.org/resteasy/docs/3.1.3.Final/userguide/html_single/…. Your missing a configuration in the web.xmlMinh Kieu

1 Answers

2
votes

I made a few mistakes, but I learned a few things.

First mistake:

For some reason I removed the @ApplicationPath() annotation over the RestEasy application path. Not having this and web.xml Wildfly didn't know what to do these classes. So they were not registered.

Putting back the @ApplicationPath() annotation, and removing the web.xml made the situation better.

Second mistake:

For some reason ( :) ), I checked the http://localhost:8000 instead of http://localhost:8080. The latter is WildFly's site. The first one is nothing.

Answering my questions:

  • Name of EAR and WAR files do not matter in this case
  • The url is created according to the following: http://{host}:{port}/{applicationPathvalue}/{pathValueOfClass}/{pathValueOfMethod}

In my case:

  • {host}: localhost
  • {port}: 8080
  • {applicationPathValue}: api (check the code sample below)
  • {pathValueOfClass}: currency (check the code in my question)
  • {pathValueOfMethod}: currencies (check the code in my question)

    @ApplicationPath("/api") public class MasterDataRestEndpointApplication extends Application {

    private Set<Object> singletons = new HashSet<Object>();
    
    public MasterDataRestEndpointApplication() {
        singletons.add(new CurrencyEndpoint());
    }
    
    @Override
    public Set<Class<?>> getClasses() {
        HashSet<Class<?>> set = new HashSet<Class<?>>();
        return set;
    }
    
    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
    

    }