JAX-RS not responding (404) - jax-rs

I have a very basic JAX-WS-RS that I'm trying to get working and am getting frustrated. And would love some help. --thanks.
my environment is Eclipse 2018-09 (fresh "dynamic web-app"), java 8u191, tomcat 8.5
my "basic" code (running in the app named: webservice) won't respond at all to calls to /webservice/steve. only a 404.
I'm including JAR: /WEB-INF/lib/javax.ws.rs-api-2.1.1.jar
code:
import javax.ws.rs.*;
#Path("/")
public class ServletTest {
#GET
#Path("/steve")
#Produces("text/plain")
public String getSteve() {return "Steve";}
}

Related

Why can't i access JAX-RS api?

I have a task from a company, that send me a virtual machine with everything set up. The task is that i have to create an API to retrieve Person details from the database and display it.
The problem is that when i run the application, the server returns an index.html with hello world text in it. However, when i try to change the index.html, it does not change in the browser, but when i do request through postman, i get the "updated" index.html.
What i also realised that i cannot access the API that i have created, to check if i can access APIs in the first place.
The path where the index.html returns is "http://hocalhost:8080/tutorial-applicans/"
My Service is PersonService.java:
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Stateless
#Path("person")
public class PersonService{
#PersistenceContext(unitName = "de.erknrw_tutorial-applicants_pu")
private EntityManager em;
#GET
#Path("hello")
#Produces(MediaType.TEXT_PLAIN)
public String sayHello(){
return "Hello World!!!"
}
}
I am trying to get "Hello World!!!", but my path is wrong, when i tried "http://hocalhost:8080/tutorial-applicans/person/hello".
Might be worth mentioning that there is also a JAXRSConfiguration.java file:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Applications;
#ApplicationPath(JAXRSConfiguration.RESTROOT)
public class JAXRSConfiguration extends Application{
public static final String RESTROOT = "webresources";
}
How do access the sayHello()? How does the path look like?
Thanks in advance
When deploying on a webapp, the JAX-RS application is configured as a Servlet. So, you have to add the application path prior to the path of the resource.
The endpoint would be:
http://[server]:[port]/[context path]/[application path]/[resource path]/[operation path]
In your case:
http://hocalhost:8080/tutorial-applicans/webresources/person/hello

Swagger api listing is empty

Recently I have configure swagger with one of my project. Its using jersey2 and JAX-WS on tomcat for restful API. I have used following manual to configure
https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-2.X-Project-Setup-1.5
${basepath}/swagger.json response with following
{"swagger":"2.0","info":{"version":"1.0.0","title":""},"host":"localhost:8080","basePath":"/myapi","schemes":["http"]}
Unfortounately it does not contain any api which is under my resource package.
I have tried with the answer of following question
swagger - empty listing with no API
But it didn't help either.
The above answer using com.wordnik.swagger.* package(s)
But with the manual I got io.swagger.* package(s), which doesn't have
JaxrsApiReader class
My assumption is swagger couldn't scan my api list from Resource package.
But could not figure out which configuration or which code snippet I have missed.
Any help?....
It looks like you forgot to mark the rest endpoints with #Api
I had the same issue, I used a different approach that worked for me, by adding information only in my Application class. In case you have one, that might help you:
public class MyApi extends Application {
public MyApi() {
super();
BeanConfig beanConfig = new BeanConfig();
beanConfig.setTitle("MyApi");
beanConfig.setVersion("0.0.1");
beanConfig.setSchemes(new String[]{"http", "https"});
beanConfig.setHost("localhost:8080");
beanConfig.setBasePath("/mypath");
//putting only the path to my api unblocked me, I removed "io.swagger.resources"
beanConfig.setResourcePackage("system.organization.api");
beanConfig.setScan(true);
beanConfig.setPrettyPrint(true);
}
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<>();
s.add(MyApis);
//for swagger
s.add(ApiListingResource.class);
s.add(SwaggerSerializers.class);
return s;
}
}
Then, the links of classes with #API annotation appeared in swagger.json
Mostly done with the same manual you used: https://github.com/swagger-api/swagger-core/wiki/Swagger-Core-Jersey-1.X-Project-Setup-1.5

How to inject EJB from different EAR in same glassfish

I have been trying to implement this design for couple of days ago and had no success. (before continuing I tell that I have read this article "How can I inject an EJB from an other application on the same GlassFish Server?" and other than glassfish-ejb-jar.xml I tried everything in it )
I have 2 ear application. test.ear is my main app which I want to test it, but I don't want to add any remote interfaces in this project, so I created another .ear(automation.ear) which contains remote interfaces and inject EJBs from test.ear . so my standalone application calls automation app and can not access test application directly.
each application contains these modules: entities, ejb , ear (for example automation application contains :automation-entities, automation-ejb, automation-ear)
here is my journey :
(I deployed test.ear before all these attempts)
-first try: I added test.ejb with ejb type as a maven dependency to automation-ejb pom.xml and injected EJB of test.ear in one of the beans of automation project and gave it a mappedName; it worked however I realized that it is a false positive and it actually doesn't go to the implementation of test.ear. it uses the copy it has (because of dependency)
- second try: I added a plugin in pom.xml of test.ear to create ejb-client for me (which only contains the interfaces and not the implementation) and added this .jar to automation pom.xml as a dependency, then injected the ejb gave it mappedName and try to deply ; well it complained about not finding the class!--> can't deploy
- third try: I added a copy of the interface I wanted to use(from test.ear) in automation.ear and removed the dependencies in pom.xml of automation. injected EJB and gave it the mappedName; tried to deploy and no luck ! still can't find the class--> can't deploy
Here are my classes:
test.ear application
package com.ericsson.test.service;
import javax.ejb.Local;
#Local
public interface TestService1 {
public String TestMethod1();
}
//////////////////////////////////////////////////////
package com.ericsson.test.service;
import javax.ejb.Local;
import javax.ejb.Stateless;
#Local(TestService1.class)
#Stateless(name = "TestService1")
public class TestServiceBean1 implements TestService1{
#Override
public String TestMethod1() {
return "Test Method1";
}
}
automation.ear application
#Remote
public interface RemoteInterfaceTest{
public void doSomething();
}
////////////////////////////////////////////////////////////////////////
package com.ericsson.test.service;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.naming.InitialContext;
#Singleton
#Startup
public class RemoteInterfaceTestBean implements RemoteInterfaceTest {
#EJB(mappedName = "Test-Server-Local/test-ejb-0.0.1-SNAPSHOT/TestService1/local")
private TestService1 testService1EJB;
#PostConstruct
public void doSomething() {
try {
InitialContext ic = new InitialContext();
TestService1 service1 = (TestService1) ic
.lookup("java:global/Test-Server-Local/test-ejb-0.0.1-SNAPSHOT/TestService1");
System.out.println(service1.TestMethod1());
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("OOOOOOPPPPPPSSSSSSSSS ! First try");
}
try {
testService1EJB.TestMethod1();
} catch (Exception e) {
System.out.println("OOOOOOPPPPPPSSSSSSSSS ! Second try");
}
}
}
and this is the exception I get:
SEVERE: Exception while deploying the app [automation-csdp-remote] : Cannot resolve reference Local ejb-ref name=com.ericsson.test.service.RemoteInterfaceTestBean/testService1EJB,Local 3.x interface =com.ericsson.test.service.TestService1,ejb-link=null,lookup=,mappedName=Test-Server-Local/test-ejb-0.0.1-SNAPSHOT/TestService1/local,jndi-name=,refType=Session
I have tried played with it like 1000 times, I checked the glass fish and the class is there, why it can not find it ? any idea would be greatly appreciated.
I am using EJB 3.x , glassfish 3.1.2 , maven 3.0.5, eclipse kepler

An EJB is in a JAR but is not found by the WAR next to in in an EAR

I have the structure described below, but I cannot make it so MyWebService has its member myService not null. The code of MyWebService is properly executed when I call the webservice. When I look at the JBoss logs, I keep seeing that MyServiceBean has several JNDI bindings allocated to it.
So how do I bind MyServiceBean to MyWebService?
Thanks!
my-ejb.jar:
#Local
public interface MyServiceBeanLocal {
...
}
#Stateless
public class MyServiceBean implements MyServiceBeanLocal {
...
}
my-web.war:
#Webservice(...)
public class MyWebService {
#EJB
MyServiceBeanLocal myService;
...
}
my-ear.ear:
* my-ear.ear
|-* my-web.war
|-* my-ejb.jar
Have you tried using MyServiceBeanLocal as a Remote interface ? You are trying to use dependency injection from a Web module and for a Local Interface .This is not actually suggested. Anyway, At first try to make the interface #Remote . If still it doesn't work try to use`Remote Look up from the Web module for your Remote interface link
I use CXF. CXF is not an EJB container, hence the issues I got.
I had to manually bind the EJBs, using their full name.

EJB Injection failure on deploy

I've got a problem exxh EJB's.
First of all, my setup: I am using GlassFish & JEE6. I have got a REST-Service packaged as a WAR and a bean packaged as an EJB-Jar. They are not inside an EAR.
The EJB should be used from the REST-WAR via #EJB, but when I try to deploy the WAR, GlassFish shows this error:
Error occurred during deployment:
Exception while deploying the app [exx-upload-1.0] : Cannot resolve reference Local ejb-ref name=com.ex.exx.model.FileUpload/ocr,Local 3.x interface =com.ex.exx.api.IOCRService,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session. Please see server.log for more details.
(The EJB was deployed before without any erros).
I have no clue why. Here is the EJB Code:
Interface:
#Local
public interface IOCRService {
public String performOCRonImage(BufferedImage input);
}
and Implementation:
#Stateless
#LocalBean
public class OCRScanner implements IOCRService {
private Logger logger = Logger.getLogger(this.getClass().getName());
private final static String NOT_RECOGNIZED = "Can not regocnize text";
/**
* Default constructor.
*/
public OCRScanner() {
logger.log(Level.INFO, "### OCR SCANNER BUILD" + this);
}
public String performOCRonImage(BufferedImage input) {
logger.log(Level.INFO, "### OCR SCANNER CALLED" + this);
}
...
And here is the important part in the WAR:
public class FileUpload {
private final File PROPERTIES_FILE = new File(
"fileUploadProperties.properties");
private final String PARAMETER_NAME = "file";
private final Logger logger = Logger.getLogger(this.getClass().getName());
#EJB
private IOCRService ocr;
public Response uploadFile(...) {
// do some stuff
logger.log(Level.INFO, "### EJB" + ocr.toString())
}
Anny suggestions? I can not find my failure here.
Solved this, by replaceing #Local with #Remote.
This works, however, I am not satisfied as I do not understand why.
Basically, given the specs (eg. explained in the tutorial), an application can only access other application's EJB, if they are decorated with #Remote.
Thus, you have 3 options:
decorate your EJB with #Remote (what you have done),
package both together inside an ear (as they would reside in the
same application then). But if you intent to deploy them in seperate
applications or even seperate servers, use 1.)
use CDI with #Inject, but this will still only discover the EJB if
either in the same application, or decorated as #Remote if not.
HTH,
Alex
You should not use #EJB if the target is not an EJB. I guess this is your case because you are trying to inject into a class in your WAR.
Instead use:
#Inject
private IOCRService ocr;
Basically, #Inject is better in most cases, because:
it is more typesafe,
it supports #Alternatives
it is aware of the scope of the injected object.
Another solution it's to add #Stateless(name=""), this worked form