How to access the endpoint assembled inside an ear file? - rest

I am building a web app using java ee as backend and angular as frontend. As application server i have chosen Wildfly 13. As a build tool for backend I have chosen Maven. I have created this structure for the project :
-Project
---Project-ear
---Project-model
---Project-service
---Project-service-api
Neither of this modules packages a war file, I package 3 jars and in the end I assemble them in an ear file using
"Project-ear"
I have tried to consume the exposed service inside
"Project-service"
but I cant. It seems I don't set the right url. Can somebody help me please?
I have tried to access the following urls:
http://localhost:8080/Project-ear/Project-service/resources/test/testDtos/,
http://localhost:8080/resources/test/testDtos/
I have created the RestActivator class :
#ApplicationPath("/resources")
public class RestActivator extends Application {
}
And I have created a Resource class :
#Path("/test")
public class TestResource {
#GET
#Path("/testDtos")
#Produces(MediaType.APPLICATION_JSON)
public Response getWorkflowDiagram() {
TestDto testDto = new TestDto();
testDto.setFirstName("Test");
testDto.setLastName("Test");
return Response.ok(testDto).build();
}
}
I don't get any error message, I just can't access the URL endpoint.

When you configure the Application Server (Wildfly) and add the ear artifact, it creates a target folder in your ear-folder. There you can find a file called application.xml. You have to set the context-root like that:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd"
version="7">
<module>
<web>
<web-uri>test.war</web-uri>
<context-root>/api</context-root>
</web>
</module>
</application>
Your URL depends on what you have set in context-root in application.xml and how have set the application path in your root class (RestActivator).
In this example:
localhost:8080/api/resources
And to get access to your method in TestResource:
localhost:8080/api/resources/test/testDtos

Related

How to define Context Path in Wildfly?

I've used the following code to set the Context Path in tomcat where I can access my application directly using localhost:8080 by overriding the tomcat's default path.
<Context path="" docBase="G:\bitbucket\projectpath\project\build\libs\project-1.0" workDir="G:\bitbucket\projectpath\project\build\libs\project-1.0\work" debug="0" reloadable="false" autoDeploy="true" unpackWARs="true" crossContext="true"/>
Now I'm going to use wildfly-8.2.0 as runtime environment. I tried by directly pasting the .war file into G:\wildfly-8.2.0.Final\standalone\deployments and I can access my project in browser like localhost:8080/project-1.0.
I need to setup the same configuration to wildfly like I've done in tomcat to access my project in localhost:8080 by overriding the wildfly's default welcome page. I tried to do the same in wildfly but I'm stuck where to do that. There are lot of .xml files in wildfly folder (when comparing with tomcat's simple server.xml file) which I get confused on where to start with. I searched using "How to set Context Path in Wildfly", but got no success. Can anyone help me on how to do it..? If it's related to coding, then I can do lot of searches and atleast I can get some Ideas, but I'm stuck here at configuration. Thanks in Advance.
You can do this in the by adding a /WEB-INF/jboss-web.xml file in the application that you deploy:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.jboss.com/xml/ns/javaee
http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
<context-root>/</context-root>
</jboss-web>
Change context-root directly in WebService class with annotation.
import org.jboss.ws.api.annotation.WebContext;
#Stateless
#WebService(portName = "SampleWSPort", serviceName = "SampleWS")
#SOAPBinding(style = Style.DOCUMENT)
#WebContext(contextRoot = "/SWS", urlPattern = "/SampleWS")
public class SampleWS implements SampleWSInterface {
org.jboss.ws.api.annotation.WebContext is in MAVEN artifact:
<dependency>
<groupId>org.jboss.ws</groupId>
<artifactId>jbossws-api</artifactId>
<version>1.1.2.Final</version>
</dependency>

Can I get servlet logging from gwt test case

I have been using GwtTestCase for a while and am trying to test a simple RestyGwt client api. I have added the servlet to my gwt.xml class but am not able to get any logging from the servlet. It appears that the servlet is not being created.
Here is my simple servlet that I have tried to get some kind of information from, including just throwing a runtime exception.
public class JerseyTestServlet extends ServletContainer {
{
System.err.println("RUNNING JERESEY TEST SERVLET");
}
private static final long serialVersionUID = -7518118461257020639L;
public JerseyTestServlet() {
super(new RestApplication());
System.out.println("RUNNING JERESEY TEST SERVLET");
throw new RuntimeException("FOOO");
}
}
The class does match the class name and package of the servlet.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.5.1//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.5.1/distro-source/core/src/gwt-module.dtd">
<module rename-to='simulator'>
<inherits name="com.testing.NgProductionClient" />
<servlet path='/rest' class='com.testing.JerseyTestServlet'/>
</module>
I want to get some kind of debugging information about the servlet when it starts up so I can troubleshoot path'ing problems as they arrise. Is it possible to get debugging information from the servlet inside a GwtTestCase?
My mistake of course. The .gwt.xml file should contain the glob path for all the rest services so in my case it needed the /rest/* . Once I did this the rest service worked for my unit tests. Also I forgot that the servlet doesn't start by default unless you give it the options to load on default but I don't know how this is possible without the test framework using a web.xml. I am happy with the solution and it makes testing a Mock'd rest client very simple.

Glassfish v3: Web application not finding JAR in the same EAR

I created a EAR application in Eclipse to run in Glassfish 3.1. The used projects are: BibliotecaEAR2 (the main EAR. 'Biblioteca' means 'Library'), BibliotecaEJB (with EJBs), BibliotecaModel (with entities and DAOs) and BibliotecaWeb (The Web application). The application.xml has this structure:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" id="Application_ID" version="6">
<display-name>BibliotecaEAR2</display-name>
<module>
<web>
<web-uri>BibliotecaWeb.war</web-uri>
<context-root>biblioteca</context-root>
</web>
</module>
<module>
<ejb>BibliotecaEJB.jar</ejb>
</module>
</application>
In BibliotecaWeb, the META-INF/MANIFEST.MF is written this:
Manifest-Version: 1.0
Class-Path: lib/google/guava-18.0.jar
// other JARs in BibliotecaEAR2 project
BibliotecaEJB.jar
When I start the glassfish I get this warning message:
2014-10-20T14:34:31.691-0200|WARNING: PWC6351: In TLD scanning, the supplied resource file:/C:/dev/glassfish3/glassfish/domains/biblioteca-glass3/eclipseApps/BibliotecaEAR2/BibliotecaEJB.jar does not exist
java.io.FileNotFoundException: C:\dev\glassfish3\glassfish\domains\biblioteca-glass3\eclipseApps\BibliotecaEAR2\BibliotecaEJB.jar (O sistema nao pode encontrar o arquivo especificado)
Although it does not stop me from running the application, I would like to eliminate it.
Googling for PWC6351 warning, I perceived that it happens when a used JAR is not found in the Manifest File. However the request JAR is not simply a external library, but a sub-project in same EAR. Is there any additional configuration that should I do?
Thanks,
Rafael Afonso
From Packaging libraries with EARs:
When packaging applications in an EAR file, the library JARs need to
be placed in the archive lib directory (jars at the archive root level
are not added to the classpath and thus available from other EAR
artifacts.)
The library jars placed in the "/lib" directory of the EAR (the
directory name can be overridden in application.xml) will be visible
to all sub-modules (JARs, WARs, and RARs) with no further
configuration. No need to add Class-Path entries in the EAR manifest.
In fact you don't need to reference the jars in the lib folder, and it looks like it will not work if you reference a jar on the EAR root level, like your BibliotecaEJB.jar.
If you don't have a real dependency from your WAR module classes to your EJB module classes you can just remove all the entries from the MANIFEST.MF and it should work.
If you instead have a real dependency from WAR to EJB, you may have to think about your project structure and if you really need an EAR. You can also package all the stuff into a single WAR.
The right way to use an EAR with WAR and EJB modules requires a little bit of work if your current WAR classes directly depend on classes from the EJB module:
1. Step
You have to create interfaces for all your "service" classes which should be available to classes in the web application (WAR).
Here is a simple example:
public interface FileService {
public void showFileInformation(File file);
}
and
#Stateless
#Local(FileService.class)
#Remote(FileService.class)
public class FileServiceImpl implements FileService {
#Override
public void showFileInformation(File file) {
// here
// is
// the
// real
// stuff
}
}
2. Step
The next step is to package all your new interfaces into a new jar. Your model jar looks similar to this approach. If this can't be used for this purpose, create a simple java application project which gets packaged as jar and put all the interfaces into this project. This jar has to be in the lib folder of the EAR.
BibliotecaEAR2
-- BibliotecaEJB
-- BibliotecaWeb
-- /lib/interfaces.jar
Then you have to add a dependency to this new jar in your WAR and EJB modules, so that they can find the interface classes.
3. Step
The services can be injected into the managed classes of your web applications (and into other service classes) like this:
#RequestScoped
public class FileHandler {
// make sure to use the interface
#EJB
FileService fileService;
}
Maybe you already have something similar to this, but then it should work without any entries in the MANIFEST.MF.
See also:
Maven2: Best practice for Enterprise Project (EAR file)
Java EE - EAR vs separate EJB+WAR
Packaging EJB in JavaEE 6 WAR vs EAR
I had a similar issue and solved by customizing module location, like this
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" id="Application_ID" version="6">
<display-name>BibliotecaEAR2</display-name>
<module>
<web>
<web-uri>BibliotecaWeb.war</web-uri>
<context-root>biblioteca</context-root>
</web>
</module>
<module>
<ejb>BibliotecaEJB.jar</ejb>
<bundleDir>/lib</bundleDir> <!-- ADD THIS OPTION TO THE MODULE -->
</module>
</application>
This solution is taken from the Maven EAR plugin documentation, which uses Maven 3 syntax, but I think you can use it too (or you can migrate to Maven 3).
Hope that helps.

How to define a custom EAR file name for a specific application?

Here is my setup
SDK: Eclipse Ganymede (3.4.2)
App Server: jBoss 4.2.3GA
I got three projects:
MYAPP, which is the main project, with only libraries and log4j configurations. This is where application.xml and jboss-app.xml resides.
MYAPPEJB, which is my business logic project in which I have my entity beans, sessions beans.
MYAPPWeb, which is my client logic project in which I have my Struts Forms, Struts Actions, JSPs and Jasperreports reports.
When I publish my project to my jBoss server on my laptop, I got the following EAR file name: MYAPP.ear, which make sense.
I would like to define a different custom name for the final EAR, let's say ACCOUNTMANAGER.ear
Here is my application.xml file
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" id="Application_ID" version="5">
<display-name>MYAPP</display-name>
<module>
<ejb>MYAPPEJB.jar</ejb>
</module>
<module>
<web>
<web-uri>MYAPPWeb.war</web-uri>
<context-root>/manager/myapp</context-root>
</web>
</module>
<library-directory>/lib</library-directory>
</application>
Any idea?
Thank you
Charles
You can specify your ear file name in application.xml file under web -> web-uri tag. Please check this link for your reference. web-uri
You can specify in application.xml file. It will pick up this name instead of ear file name.
MyEarName

Arquillian test with real EAR from build on JBoss 7.1

I want to test an Java EE application with Arquillian. A simple setup is working to put some test classes onto the server managed by Arquillian to test them.
Now, I want to use a EAR file which was build during the build process. With
#Deployment
public static EnterpriseArchive createDeployment() {
File earFile = ...
EnterpriseArchive archive = ShrinkWrap.createFromZipFile(EnterpriseArchive.class, earFile);
return archive;
}
I am able to put the EAR via Arquillian to JBoss. I see the deployment and there are no errors during deployment. Only Arquillian returns with an error that it can not find the test class, which is obviously ok.
Now is the question where to put the test class to. I can put the test class into the test.war put into the EAR by Arquillian, but I get an ArquillianServletRunner not found exception. When I put the test classes into JAR files as module or library the test classes are not found when put as module or the injects do not work when put as libraries due to dependency issues.
Where to I have to put the test classes to???
My arquillian.xml:
<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://jboss.org/schema/arquillian"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<defaultProtocol type="Servlet 3.0" />
<container qualifier="jboss7" default="true">
<configuration>
<property name="jbossHome">${cargo.dir}/jboss-as-dist-7.1.1.Final/jboss-as-7.1.1.Final</property>
</configuration>
</container>
<engine>
<property name="deploymentExportPath">target/deployments</property>
</engine>
</arquillian>
You can run your test class on the client side using #Deployment(testable = false), but this has the downside that you cannot use the persistence extention (and maybe others) at the moment.
My example code:
#RunWith(Arquillian.class)
public class PersonWebServiceIT {
private PersonWebService service;
#Deployment(testable = false)
public static Archive<?> createDeployment() {
return ShrinkWrap
.create(ZipImporter.class, "test.war")
.importFrom(
new File("simple-webservice-1.0.0-SNAPSHOT.war"))
.as(WebArchive.class);
}
#Test
public void testFindPersons(#ArquillianResource URL deploymentUrl) {
....
}
}
Putting the test classes to the war inside the ear did work for me
WebArchive war = ear.getAsType(WebArchive.class, "/mywarname.war");
war.addClass(MyTestClass.class);
When I am dealing with existing EAR, I prefer to separate the WAR that runs the tests, from the actual tests that I put in special JAR along with other testing EJBs. I have posted an example how do I do it with the necessary application.xml manipulation under similar question: https://stackoverflow.com/a/17036383/1667977