cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with exposing a simple Java OData webservice (with odata4j)...

Former Member
0 Kudos

Dear experts,

though the OData issue is very new I hope to find someone here to help me out with some experience. I'm using SAP NetWeaver 7.3 SP07 PAT0002 and I'm trying to inplement a java OData service with the framework odata4j.

My steps were so far:

  1. I created an external library DC and wrapped it with an EAR.
  2. I created a J2EE Web module DC for the OData web service and wrapped it with another EAR.
  3. I implemented the InMemoryProducer example from here.
  4. I searched for evry missing class in internet and added it when found. (unfortunately it's been several classes)
  5. I ran the main class "as Java Application" - it printed an URL on the console where to find the WADL. It was there. (I won't put the WADL here because of it's size. If needes, I'll hand it out later.)
  6. I found the "root" URL by chance where the OData entities are exposed. (see below)
  7. I deleted all methods in the main-Method "producer.register(...)" except of exposing Integers (as working example), and implemented a register-Method for my own little objects for testing, from class "Thing". (see below)
  8. --> trying to go into the category "Things" which shall expose "Thing" objects failed, "Internal Server Error"

Until now it's been only local. For deploying it on netweaver I made the following steps so far:


  1. I altered the web.xml of the Odata Web Module and the application.xml of the corresponding EAR. (see below)
  2. I deployed the library EAR, then the OData EAR, both succeeded.
  3. I tried to call the URL of the Web Project - it said "not authorized". I tried the OData root URL, it said : 404 not found, Error: Request cannot be processed. Details: Requested resource [OData] is not found.

My questions are:

  • Why can't the server find the OData resource? And which "resource" is meant? Can't he find the library? Can't he find the servlet specified in the web.xml which is named "OData"?
  • Why isn't my "Things" exposed locally? It works with the Integers, but not with any other classes of this example, even so not with my own objects.

-----------------------------------------------------------------

Now all the source codes that are necessary to know:

-----------------------------------------------------------------

The altered InMemoryProducerExample with only two register-Methods:

package testWebservice;

... // I cut out all imports that are unchanged

import testEntities.Thing;

public class InMemoryProducerExample extends AbstractExample {

    public static void main(String[] args) {

        InMemoryProducerExample example = new InMemoryProducerExample();

        example.run(args);

    }

    private void run(String[] args) {

        String endpointUri = "http://localhost:8887/InMemProducer/";

        // InMemoryProducer is a readonly odata provider that serves up POJOs as

        // entities using bean properties

        // call InMemoryProducer.register to declare a new entity-set, providing

        // a entity source function and a propertyname to serve as the key

        final InMemoryProducer producer =

            new InMemoryProducer("InMemoryProducerExample", null, 100, new MyEdmDecorator(), null);

        // expose my own THING entity

        producer.register(Thing.class, "Things", new Func<Iterable<Thing>>() {

            public Iterable<Thing> apply() {

                return (Iterable<Thing>)new Thing().getSetofDings();

            }

        }, "Key") ;

        // expose an large list of integers as an entity-set called "Integers"

        producer.register(Integer.class, Integer.class, "Integers", new Func<Iterable<Integer>>() {

            public Iterable<Integer> apply() {

                return Enumerable.range(0, Integer.MAX_VALUE);

            }

        }, Funcs.method(Integer.class, Integer.class, "intValue"));

        // register the producer as the static instance, then launch the http

        // server

        DefaultODataProducerProvider.setInstance(producer);

        this.rtFacde.hostODataServer(endpointUri);

    }

.... //  I cut out the un-altered code for MyEmDecorator

}

Now my very own class "Thing": 

(it's not very nice, I know, it's just for testing)

package testEntities;

import java.util.ArrayList;

import java.util.Iterator;

public class Thing implements Iterable<Thing>{  

    private String name;

    private String kind;

    private int age;

    public Thing(String name, String kind, int age){

        this.setAge(age);

        this.setName(name);

        this.setKind(kind);

    }

    public Iterable<Thing> getSetofDings(){       

        ArrayList<Thing> things = new ArrayList<Thing>();

        things.add(new Thing("handkerchief", "textile", 2));

        things.add(new Thing("telephone", "device", 10));

        things.add(new Thing("guniea pig", "pet", 7));

        return things;

    }  

    public Thing(){       

    }

    ...  //  I cut out all getters and setters

    @Override

    public Iterator<Thing> iterator() {       

        return this.getSetofDings().iterator();

    }    

}

The web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

id="WebApp_ID" version="2.5">

  <display-name>LocalDevelopment~lib~ws~odata~gisa.de</display-name>

     <servlet>

        <servlet-name>OData</servlet-name>

         <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>

        <init-param>

            <param-name>javax.ws.rs.Application</param-name>

            <param-value>org.odata4j.jersey.producer.resources.ODataApplication</param-value>

        </init-param>

        <init-param>

            <param-name>odata4j.producerfactory</param-name>

            <param-value>InMemoryProducerExample</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

        <servlet-name>OData</servlet-name>

        <url-pattern>/InMemProducer/*</url-pattern>

    </servlet-mapping>

</web-app>

The application.xml:

<?xml version="1.0" encoding="ASCII"?>

<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" version="5">

  <display-name>LocalDevelopment~lib~ws~odata~ear~gisa.de</display-name>

  <module>

    <web>

      <web-uri>gisa.de~lib~ws~odata.war</web-uri>

      <context-root>odata</context-root>

    </web>

  </module>

</application>

The exposed OData Root URL (local):  http://localhost:8887/InMemProducer/

<?xml version="1.0" encoding="utf-8" ?>

- <service xmlns="http://www.w3.org/2007/app"
<workspace>

<atom:title>Default</atom:title> -
<collection href="Things">
<atom:title>Things</atom:title>

</collection>- <collection href="Integers">

<atom:title>Integers</atom:title>

</collection>

</workspace>

</service>

If you need something else, please let me know.

Thanks for your kind support.

Regards

Jana

Accepted Solutions (0)

Answers (5)

Answers (5)

stefan_heitzer
Participant
0 Kudos

Hey Jana,

good news for you! I have the solution!

We just changed the Odata4j version from 0.7 to 0.6 and then it worked! We had also to change the keys for our own producer.register(); but afterwards everything worked perfektly

But now I have another problem. I can start the service without any problems and I can also modify the url like *.svc/Systems?$filter=Name eq 'Test'

But now I want to capture these information in the url. I've already found out that there is a function called getEntities but I actually have no clue how it works. Maybe somebody can help

Greetings!

stefan_heitzer
Participant
0 Kudos

Hey,

I have the same problem here.

I took also the same example and only added the following coding:

    producer.register(String.class, "Systems", new Func<Iterable<String>>() {

        public Iterable<String> apply() {

          List<String> customers = new ArrayList<String>();

          customers.add("test");

          return customers;

        }

      }, "Id");

When I open the *.svc file I see Systems but after I entered *.svc/Systems I just get the following code:

<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">

<code>ServerErrorException</code>

<message lang="en-US">Internal Server Error</message>

</error>

Have you already found a solution for this problem? Would be very grateful!

Greetings

Former Member
0 Kudos

Hi Stefan,

unfortunately, I didn't have any replys anywhere else and couldn't find the solution myself.

Because of the missing documentation, exapmles and tutorials for OData, I had to skip my efforts for this kind of web service and went back to REST and SOAP.

But if I ever find a solution I'll post it here, too. 🙂

Greetings

Jana

Former Member
0 Kudos

The full error log is as follows:        (I forgot to add it before)

Cannot process an HTTP request to servlet [OData] in [odata] web application.
[EXCEPTION]
com.sap.engine.services.servlets_jsp.server.exceptions.ServletNotFoundException: Requested resource [OData] is not found.
at com.sap.engine.services.servlets_jsp.server.application.WebComponents.getServlet(WebComponents.java:823)
at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.runServlet(HttpHandlerImpl.java:376)
at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.handleRequest(HttpHandlerImpl.java:210)
at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:441)
at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:430)
at com.sap.engine.services.servlets_jsp.filters.DSRWebContainerFilter.process(DSRWebContainerFilter.java:38)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.servlets_jsp.filters.ServletSelector.process(ServletSelector.java:81)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.servlets_jsp.filters.ApplicationSelector.process(ApplicationSelector.java:276)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.httpserver.filters.WebContainerInvoker.process(WebContainerInvoker.java:81)
at com.sap.engine.services.httpserver.chain.HostFilter.process(HostFilter.java:9)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.httpserver.filters.ResponseLogWriter.process(ResponseLogWriter.java:60)
at com.sap.engine.services.httpserver.chain.HostFilter.process(HostFilter.java:9)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.httpserver.filters.DefineHostFilter.process(DefineHostFilter.java:27)
at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.httpserver.filters.MonitoringFilter.process(MonitoringFilter.java:29)
at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.httpserver.filters.SessionSizeFilter.process(SessionSizeFilter.java:26)
at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.httpserver.filters.MemoryStatisticFilter.process(MemoryStatisticFilter.java:57)
at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.httpserver.filters.DSRHttpFilter.process(DSRHttpFilter.java:43)
at com.sap.engine.services.httpserver.chain.ServerFilter.process(ServerFilter.java:12)
at com.sap.engine.services.httpserver.chain.AbstractChain.process(AbstractChain.java:78)
at com.sap.engine.services.httpserver.server.Processor.chainedRequest(Processor.java:475)
at com.sap.engine.services.httpserver.server.Processor$FCAProcessorThread.process(Processor.java:269)
at com.sap.engine.services.httpserver.server.rcm.RequestProcessorThread.run(RequestProcessorThread.java:56)
at com.sap.engine.core.thread.execution.Executable.run(Executable.java:122)
at com.sap.engine.core.thread.execution.Executable.run(Executable.java:101)
at com.sap.engine.core.thread.execution.CentralExecutor$SingleThread.run(CentralExecutor.java:328)
Caused by: java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer
------------------------- Loader Info -------------------------
ClassLoader name: [gisa.de/lib~ws~odata~ear]
Loader hash code: 5081e0d8
Living status: alive
Direct parent loaders:
   [system:Frame]
   [interface:webservices]
   [interface:cross]
   [interface:security]
   [interface:transactionext]
   [library:webservices_lib]
   [library:opensql]
   [library:jms]
   [library:ejb20]
   [service:p4]
   [service:ejb]
   [service:servlet_jsp]
Resources:
   E:\usr\sap\L19\J30\j2ee\cluster\apps\gisa.de\lib~ws~odata~ear\servlet_jsp\odata\root\WEB-INF\classes
---------------------------------------------------------------
at com.sap.engine.boot.loader.MultiParentClassLoader.loadClass(MultiParentClassLoader.java:278)
at com.sap.engine.boot.loader.MultiParentClassLoader.loadClass(MultiParentClassLoader.java:247)
at com.sap.engine.services.servlets_jsp.server.application.WebComponents.getResourceClass(WebComponents.java:1902)
at com.sap.engine.services.servlets_jsp.server.application.WebComponents.getServlet(WebComponents.java:798)
... 37 more

Former Member
0 Kudos

One thing I found out so far:

The [OData] resource which is not found is the one mentioned in web.xml as "servlet-name". I prooved this by altering this name - the error message altered too.

Kind regards

Jana

Former Member
0 Kudos

Somehow the xml files have beent deleted. Here's the code (hopefully it will still be there after beeing "moderated" 😉 )

web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" x

mlns="http://java.sun.com/xml/ns/javaee"

xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

id="WebApp_ID" version="2.5">

  <display-name>LocalDevelopment~lib~ws~odata~gisa.de</display-name>

     <servlet>

        <servlet-name>OData</servlet-name>

         <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>

        <init-param>

            <param-name>javax.ws.rs.Application</param-name>

            <param-value>testWebservice.InMemoryProducerExample</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

        <servlet-name>OData</servlet-name>

        <url-pattern>/InMemProducer/*</url-pattern>

    </servlet-mapping>

</web-app>

application.xml:

<?xml version="1.0" encoding="ASCII"?>

<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" x

mlns="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" version="5">

  <display-name>LocalDevelopment~lib~ws~odata~ear~gisa.de</display-name>

  <module>

    <web>

      <web-uri>gisa.de~lib~ws~odata.war</web-uri>

      <context-root>odata</context-root>

    </web>

  </module>

</application>

Kind regards

Jana