Google Summer of Code -- Integration of Apache CXF JAX-RS with EJB
Dear CXF Developer's Mailing List, My name is Ryan Zoerner and I am a Computer Sciences Major at the University of Wisconsin Madison. I am writing to subscribe to this mailing list because I am interested in working on Integrating Apache CXF JAX-RS with EJB, and that, in conjunction with Google Summer of Code. If this is not the correct address to send this message to, I will resend it when I have been added to the list. A bit about my experience as it relates to this project: I am interested in web services and web programming. A few summers ago, I spent time going through the Java EE 5 tutorial and learning, from their ant files, and the ant manual, how to build my own ant files and deploy servlets and web services, including using ws-import. Now I have been going through the Java EE 6 samples to refresh my memory about ant and learn more about deploying and developing web applications. I know about wsdl, soap, xml, and xml schemas; I can read WSDL and know that it only has a few different forms basically, but I am completely comfortable writing xml, and reading xml schemas, and dtd's. I have been learning, now, about Java Server Faces and have skimmed through and am now reading more thoroughly, the Java Server Faces specification (2.1) I know about MVC. I have read a book on Service Oriented Architecture, about 3 years ago, which focused on the Enterprise Service Bus and loose coupling and how these provided a means for applications to communicate with each other. SOA has it's origins in trying to make a bunch of legacy code applications work together, and potentially, across multiple business addresses. I am familiar with annotations and have as one of my next items to accomplish, to program a basic product-saleing web app which makes use of the entity manager from Java EE. My present accomplishment (which isn't much) is that I have created a web app consisting of two xhtml pages and 2 managed beans, which accepts a user login name and password, looks them up in Derby, using JDBC in java code, and redirects to the new page, via a CommandButton which, corresponds to a UICommand component in the component tree. The project packages into a correct WAR web module; compiles from src into build, assembles the archive in build and war's to build, then copies to dist. Until now, I have just written the web address for the redirect in the html form, but I am trying to find out the best way to utilize the component tree directly without doing anything with my components which is already handled by the lifecycle processes which happen around the component tree, since state management and data access, for instance, are already covered. I have had data structures (in Java), operating systems (in C), (some) algorithms, and I have had machine programming and a C++ class also. I am interested in doing this project because of the importance of its implementation to the complete and correct implementation of the overall project. I am already familiar with java beans, jsf (thus the component processing/view rendering lifecycle and the application model). I noticed pipelining in the CXF architecture guide and I have already, much earlier, been interested in Cocoon and xml parsers because of the robustness -- although, at the time, a complaint of too much processing time for parsing, existed -- of the application. Cocoon, which some or all of you might know, is for the distribution of online content in various formats and can convert the same xml document into html, pdf, wml, etc. The power of this is that you only have to change one, possibly three documents, in order to edit the content that is being distributed to so many multiple formats. So, because of that, and because of a machine programming class, I have some exposure to pipelining. I have an interest in web services because of the separation of concerns aspect and because of the unique approach of uri-based resources. Also, I have used a time-card reporting program, through the web (called Kronos) which presented a client-web-view which was done in some form of java gui, though it did not look like another swing web-app that I have used. I admire this program because it doesn't really do that much. It just keeps track of time-card information. Yet, when properly saled, it generates large amounts of income. Not only that, although it used a gui, it loaded relatively quickly, but passes back and receives the user-generated-, and office-record- information via the server. I am not sure if this is a web-service or not, but it is possible that the employee database lives at the employer office, but is connected to, via the server, at Kronos. Whatever the case, after I saw this program, I fell in love with the idea of being able to present the user with a rich user interface, while also minimizing response time by keeping as much of the application as possible back on the server. Now, with web services, I like the idea of being able
general project setup and utilization questions
Dear Team, I've assembled a small list of questions which I don't have answers to yet. It is probable that some or all of you have encountered these questions in the process of working on this project. Therefore, if you have a quick answer, that would be helpful. Thank you. Ryan eclipse setup questions: I set cxf-systests-jaxrs up as a faceted Java Web Project in Eclipse, but because I tried it in several different ways, I am wondering: is there some preferred way to the projects up in eclipse? (e.g., Java, Dynamic Web, etc. ) -- src/ test.java test.resources eclipse cannot resolve import="org.apache.(...) how do I set file-folder-structure up so that I have src.test.java/ and src.test.resources/ as src folders on the build path. Eclipse won't let me touch those subfolders from configure buildpath (wizard?). What I would like to do is add src "folders" which contain those multiple folders in one src folder path. Junit and Eclipse I've never used Junit before, but I understand that it is a convenience library and reporting system. I see the Junit commands such as assert(), but I am unsure about how to make use of this in Eclipse. Because there is no main() method, how are the tests run? Is there some central file that calls these? Is that file part of Eclipse or the project? Server Deployment I have a Glassfishv3 server installed and setup in Eclipse, but I don't see any infrastructure for deploying web-archives (with the project). So, basically, do you deploy this to the server to test parts of it, and if so, is there some sort of test-container that you are using to encapsulate the parts that you want to test? File Search: I'm having problems searching for strings in files because of what I think are special characters in the files. This is the ouput: Problems encountered during text search. File 'cxf-systests-jaxrs/target/site/pmd.html' has been skipped, problem while reading: ('${outputEncoding}'). ${outputEncoding} Now, is there any way to use file search so that I can get around this problem. I know about regexp for instance, but if there is some default answer I would like to know. - Again, thanks for your help.
new to irc, did not have log file set to log conversation
Sergey, Yesterday, when we chatted, I had just downloaded Chatzilla and did not have the logging feature set to be on. Then, when I closed the application, I realized that I had just erased the conversation if the program didn't automatically save it, which it does not. Do you happen to have a copy of that conversation in your irc log files that you could email to me? Consequently, I don't remember what you said, pertaining to specific tasks I should do, other than that I should focus on invokers. Also, I'm going to have a hard time deploying this EJB3 container on Glassfish without more specific instructions about what and how to deploy ( what -- which files; how -- how am I supposed to build it? ) Thanks, Ryan
Re: Can't run corba unit tests?
Benson, When you set up the project in eclipse. When you typed 'mvn install -Pfastinstall -fn', there was an error in the corba setup. At the time, I had thought that I needed to put the CORBA plugin into eclipse, so I pulled it down from online, but that was not the error. You actually needed to run the command that I just listed twice, for whatever reason. I think that that might fix your problem. Ryan On Mon, Apr 25, 2011 at 5:32 PM, Benson Margulies wrote: > More detail: > > Failed tests: > > > testFixedBindingGeneration(org.apache.cxf.tools.corba.processors.WSDLToCorbaBindingTest): > expected:<[fixed_1]> but was:<[any]> > > > testCORBABindingGeneration(org.apache.cxf.tools.corba.processors.WSDLToCorbaBindingTest): > expected:<{http://cxf.apache.org/bindings/corba}any> but > was:<{http://cxf.apache.org/bindings/corba}string> > > Tests in error: > > > testSequenceType(org.apache.cxf.tools.corba.processors.WSDLToCorbaBindingTest): > org.apache.cxf.binding.corba.wsdl.CorbaTypeImpl cannot be cast to > org.apache.cxf.binding.corba.wsdl.Fixed > > > > On Mon, Apr 25, 2011 at 6:22 PM, Benson Margulies > wrote: > > [ERROR] > > [ERROR] Please refer to > > /Users/benson/asf/cxf/tools/corba/target/surefire-reports for the > > individual test results. > > [ERROR] -> [Help 1] > > [ERROR] > > [ERROR] To see the full stack trace of the errors, re-run Maven with > > the -e switch. > > [ERROR] Re-run Maven using the -X switch to enable full debug logging. > > [ERROR] > > [ERROR] For more information about the errors and possible solutions, > > please read the following articles: > > [ERROR] [Help 1] > > http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException > > [ERROR] > > [ERROR] After correcting the problems, you can resume the build with the > command > > [ERROR] mvn -rf :cxf-tools-corba > > >
Re: Can't run corba unit tests?
Did you run the install twice? Do you have a log of the install? Are there errors in the CORBA package installing? If you can verify from the log that there were no errors, then, I don't know what the other problem is. Sorry. Ryan On Mon, Apr 25, 2011 at 8:15 PM, Benson Margulies wrote: > Ryan, this isnt' a fastinstall or an eclipse issue, it's the unit tests > failing? > > On Mon, Apr 25, 2011 at 8:56 PM, Ryan Zoerner > wrote: > > Benson, > > > > When you set up the project in eclipse. When you typed 'mvn install > > -Pfastinstall -fn', there was an error in the corba setup. At the time, I > > had thought that I needed to put the CORBA plugin into eclipse, so I > pulled > > it down from online, but that was not the error. You actually needed to > run > > the command that I just listed twice, for whatever reason. I think that > that > > might fix your problem. > > > > Ryan > > > > > > On Mon, Apr 25, 2011 at 5:32 PM, Benson Margulies >wrote: > > > >> More detail: > >> > >> Failed tests: > >> > >> > > testFixedBindingGeneration(org.apache.cxf.tools.corba.processors.WSDLToCorbaBindingTest): > >> expected:<[fixed_1]> but was:<[any]> > >> > >> > > testCORBABindingGeneration(org.apache.cxf.tools.corba.processors.WSDLToCorbaBindingTest): > >> expected:<{http://cxf.apache.org/bindings/corba}any> but > >> was:<{http://cxf.apache.org/bindings/corba}string> > >> > >> Tests in error: > >> > >> > > testSequenceType(org.apache.cxf.tools.corba.processors.WSDLToCorbaBindingTest): > >> org.apache.cxf.binding.corba.wsdl.CorbaTypeImpl cannot be cast to > >> org.apache.cxf.binding.corba.wsdl.Fixed > >> > >> > >> > >> On Mon, Apr 25, 2011 at 6:22 PM, Benson Margulies < > bimargul...@gmail.com> > >> wrote: > >> > [ERROR] > >> > [ERROR] Please refer to > >> > /Users/benson/asf/cxf/tools/corba/target/surefire-reports for the > >> > individual test results. > >> > [ERROR] -> [Help 1] > >> > [ERROR] > >> > [ERROR] To see the full stack trace of the errors, re-run Maven with > >> > the -e switch. > >> > [ERROR] Re-run Maven using the -X switch to enable full debug logging. > >> > [ERROR] > >> > [ERROR] For more information about the errors and possible solutions, > >> > please read the following articles: > >> > [ERROR] [Help 1] > >> > http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException > >> > [ERROR] > >> > [ERROR] After correcting the problems, you can resume the build with > the > >> command > >> > [ERROR] mvn -rf :cxf-tools-corba > >> > > >> > > >
Re: Can't run corba unit tests?
Benson, The other thing that I just thought of is that when you did eclipse setup, it should have created a workspace folder, in the same directory as your cxf folder. In that folder are two files. One of them is called cxf-checkstyle-corba.xml . If you are using some other workspace, that might be making a difference also. But again, I'm not sure. I actually missed the workspace myself, the first time, as I have quite a few workspaces. Hopefully, that will help, but if not, at least you know what the problem is not. Ryan
Re: Can't run corba unit tests?
Benson, Sorry, I didn't read your error report well. It looks like you are doing mvn install. Is that what the generated the error report? You said that it was not. If you are doing some other setup, such as a demo setup, then I don't know the correct answer. If you tell what maven command resulted in the error report, that would be helpful. Ryan On Mon, Apr 25, 2011 at 8:56 PM, Ryan Zoerner wrote: > Benson, > > The other thing that I just thought of is that when you did eclipse setup, > it should have created a workspace folder, in the same directory as your cxf > folder. In that folder are two files. One of them is called > cxf-checkstyle-corba.xml . If you are using some other workspace, that might > be making a difference also. But again, I'm not sure. I actually missed the > workspace myself, the first time, as I have quite a few workspaces. > > Hopefully, that will help, but if not, at least you know what the problem > is not. > > > Ryan > >
Re: Can't run corba unit tests?
If the command is actually listed at the bottom of the report, I didn't know. Sorry.
general comments about cxf and my progress towards completing integrating JAX-RS CXF with EJB
a customer service and a customer associated purchases system, and they are on two different urls, then you might be able to interface between the two services utilizing the message passing system of CXF [If this is incorrect, please let me know]. I already see that most of the Interceptor duties seem to be related to delivering unexpected situations that arise, to some other place in the form of a message. If I am wrong about this, does CXF provide some mechanism for services to communicate with each other through it, or is that simply the job of the service implementor, to create all of this themselves? In using the http demo, it occurred to me that it might be better to have a ComplexEntity class, instead of a Customer class and a ComplexEntityService class instead of a CustomerService class. This would enable the user to pass any ComplexEntity to these classes, and using reflection, obtain the same result every time. The other thing that I thought of here is that it might be a good idea to have a PrimaryIdentifier annotation for the xml field that you would like to use as the primary key for locating the ComplexEntity. For instance, with Customers, the PrimaryIdentifier would be the long value: id. I have seen the ClientFactory and am impressed with the utility of it, given that you can supply only the basic necessary details and obtain a client. However, taking away the need to code individual files to deal with a Customer, or an Order, might be a nice addition. The other thing that I note here is that I see that there is a code-gen mechanism and I think that there is a xsd2java mechanism, but whether or not this can create a Customer class from a superClass such as turning ComplexEntity into Customer by substituting Customer in place of the appearance of ComplexEntity, I do not know. In theory, it might be nice to make an xsd generator that would set "one or more" by default, and certain other, potentially configurable, default values, so that java classes for complex entities could be created from a simple xml file and a corresponding xsd file might also be created, or at least a template, from the xml. Ok. So, back to the project. The files that I am now focusing on are the 5 that I named above. I think that this is the key to invoking upon EJB beans, and that everything else in the process might be taken for granted as being not part of the properties mapped to the Server (or? Client) that involve instantiating, injecting depencies upon, and invoking upon, the ejb and ejb method. I say mapped to the server, but I mean it in regards to the xml-idea that I mentioned above. That there are a set of classes attached to the Server, like trees, with the trunk ending up in the ServerFactory, or one of the classes that it calls. Just basic programming, I guess, but it helps me eliminate, in my mind the things that I won't need to look at in order to make this work (hopefully). If I've said anything in all of this that doesn't make any sense, or if you have any corrections to the things that I've said, or if you have any questions about what I said, or if you have any suggestions. Please feel free to comment. Thank you. Ryan Zoerner
Basic Http Demo and the refactoring that I did, in the course of figuring out how it worked.
I've decided that I am not posting enough about my actual coding to the dev list. In an effort to set a better backdrop for conversations about my current progress, and level of learning, I've decided to try and fix that. This email is the first of what will be numerous emails, talking, in a little detail about what actual coding I have worked on and to what effect. I also will probably make mention of some of the various pitfalls that I've encountered and what I did to fix the problem. I may also, at some times post some questions about things that I have not been able to figure out, as I think that it might aid the discussion process. That said, here is the first of what I intend to have be numerous emails to the list. JAX_RS/demo At cxf/distribution/src/main/release/samples/jax_rs/basic ( http://svn.apache.org/viewvc/cxf/trunk/distribution/src/main/release/samples/jax_rs/basic/) is a basic http demo. I found the client code to be large and unwieldly, so I refactored it. I also found it hard to understand, at first, but the key, with the GET request is that the client opens a connection with the server, at the URI associated with a given resource. The client opens a printStream that is associated with the connection, and from that connection the client obtains the return information that would normally be associated with a GET request. It may be that since the only @Path in CustomerService with "/customerservice/customers/{id}" is the GET method, that the service automatically just queries that @Path and assumes a GET request, since that method is annotated with the @GET annotation. If you annotated it with more than one HTTP RequestType, I am unsure what would happen at the moment. That said, here is the refactoring part of the code. Client.java --- /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unewlineess required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package demo.jaxrs.client; import ... public final class Client { private Client() {} /** * This client should run batch processing on file input using the methods * of CustomerService. You shouldn't have to call the methods of any * ComplexEntity. * * @param args * @throws Exception */ public static void main(String args[]) throws Exception { // sends a URL to "/customerservice/customers/123" and prints the returned // xml to the screen. printGETCustomerFromID(123); newline(); // sends a URL to "/customerservice/orders/223/products/323" and prints the returned // xml to the screen. printGETProductFromID(223, 323); printGETProductFromID(224, 324); printGETProductFromID(225, 325); newline(); updatePUTCustomerDataFile(); newline(); addPOSTCustomerDataFile(); newline(); System.exit(0); } private static void printGETCustomerFromID(long customerID) throws MalformedURLException, IOException, Exception { System.out.println("Sent HTTP GET request to query customer info"); URL url = new URL("http://localhost:9000/customerservice/customers/"; + customerID); System.out.println(url); // equivalent to url.openConnection().getInputStream(); // it gets an InputStream from the java.net.URLConnection associated with the // supplied URL. InputStream in = url.openStream(); // this is equivalent to calling url.openConnection().getContent() // or, you can use shorthand by calling url.getContent(). The important // thing to note is that a connection has actually been opened; there is // no such thing as url content, that is not associated with you opening // a connection through that url, being stored on the server in the absence // of a url request. This seems silly, but if you call url.getHeader(2);, // it makes one wonder how the url object or the server simply new what // item 2 of the headers would look like without generating all of them, // which it must do; and in the case it generates a full response to the // request, but the methods enable you to treat it as though it is stored // data, when in actuality, it is reprocessed on each method call. // ( .openConnection() ) System.out.println(getStringFromInputStream(in)); newline(); } ... } -
Re: general comments about cxf and my progress towards completing integrating JAX-RS CXF with EJB
Sergey, Thank you for the instructive assignment and for the more complete information regarding cxf-jaxrs and its implementation. I found both to be helpful. I will be publishing some of the code from them now, in an effort to set a better backdrop for good communication, along with enabling me to ask more questions, if necessary. Thanks. Ryan
demo.jaxrs.server.CustomInvoker
In the course of the assignment that Sergey provided me with, I augmented the http-demo, which I talked a bit here: http://cxf.547215.n5.nabble.com/Basic-Http-Demo-and-the-refactoring-that-I-did-in-the-course-of-figuring-out-how-it-worked-td4389413.html Now, the purpose of this customInvoker was for the Server to print a message to the the terminal each time a method was invoked. Here is the code: demo.jaxrs.server.CustomInvoker.java -- package demo.jaxrs.server; import java.lang.reflect.Method; import org.apache.cxf.jaxrs.JAXRSInvoker; import org.apache.cxf.jaxrs.lifecycle.ResourceProvider; import org.apache.cxf.jaxrs.model.ClassResourceInfo; import org.apache.cxf.jaxrs.model.OperationResourceInfo; import org.apache.cxf.jaxrs.utils.InjectionUtils; import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.message.Exchange; public class CustomInvoker extends JAXRSInvoker { public CustomInvoker() { super(); } @Override public Object invoke(Exchange exchange, Object request) { ResourceProvider provider = getResourceProvider(exchange); Object rootInstance = getServiceObject(exchange); Object serviceObject = getActualServiceObject(exchange, rootInstance); OperationResourceInfo ori = exchange.get(OperationResourceInfo.class); ClassResourceInfo cri = ori.getClassResourceInfo(); /* * This is where the method to be invoked upon is gotten from. */ Method methodToInvoke = InjectionUtils.checkProxy(cri.getMethodDispatcher().getMethod(ori), serviceObject); /* * This prints the message to the terminal about which method will now * be invoked upon through the server code. */ System.out.println( "\n" + "***" + "\n" + "The method about to be invoked" + "\n" + "by the CustomInvoker" + "\n" + "is named" + "\n" + "--->" + " " + methodToInvoke.getName() + "\n" + "***" + "\n" ); /* * This calls the invoke method of the org.apache.cxf.jaxrs.JAXRSInvoker * which invokes upon the method which is obtainable from the * exchange Object, as demonstrated by this method of this sub-class. */ return super.invoke(exchange, request); } /* * Because this method was private, I had to copy-and-paste it from the * superclass. Another thing that I just thought of is that if you need * to throw exceptions from, say, JAXRSInvoker, you won't get all of the * resources that you need if you just copy-and-paste and change the * package name. Therefore, you could, instead, make a subclass and just * @Override what you have copied and pasted, then insert your exceptions. */ private ResourceProvider getResourceProvider(Exchange exchange) { Object provider = exchange.remove(JAXRSUtils.ROOT_PROVIDER); if (provider == null) { OperationResourceInfo ori = exchange.get(OperationResourceInfo.class); ClassResourceInfo cri = ori.getClassResourceInfo(); return cri.getResourceProvider(); } else { return (ResourceProvider) provider; } } } -- This helped me see, better, what the invoker is actually doing with its code, and how simple it is to do surgical alterations of coded applications, without having to know much about what else is actually happening. This has application to the integration because EJB needs to have its resources injected at the time of Construction, according to JAX-RS 1.1, and EJB annotations must be processed, during any method invokation, which is what the invoker is doing here is calling the method of a resource whose lifecycle is being governed by a org.apache.cxf.jaxrs.lifecycle.ResourceProvider. In this case, org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider. I also had to create a CustomResourceProvider, which I may also publish to the list in a subsequent email. Ryan
Server output as a result of the CustomInvoker and Client output after parameterization refactoring of Client, CustomerService, and Order
This is follow-up info to the things that I discussed here: http://cxf.547215.n5.nabble.com/Basic-Http-Demo-and-the-refactoring-that-I-did-in-the-course-of-figuring-out-how-it-worked-td4389413.html and here: http://cxf.547215.n5.nabble.com/demo-jaxrs-server-CustomInvoker-td4389484.html Custom Invoker: Here is the terminal output from the Server which has registered a CustomInvoker. The registration was done in Server.java here: Server.java ... sf.setInvoker(new CustomInvoker()); ... and here is the new output: mvn -Pserver There are no tests to run. Results : Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] >>> exec-maven-plugin:1.2:java (default) @ jax_rs_basic >>> [INFO] [INFO] <<< exec-maven-plugin:1.2:java (default) @ jax_rs_basic <<< [INFO] [INFO] --- exec-maven-plugin:1.2:java (default) @ jax_rs_basic --- product 323 product 324 product 325 May 12, 2011 3:18:08 AM org.apache.cxf.endpoint.ServerImpl initDestination INFO: Setting the server's publish address to be http://localhost:9000/ May 12, 2011 3:18:09 AM org.eclipse.jetty.util.log.Slf4jLog info INFO: jetty-7.3.1.v20110307 May 12, 2011 3:18:09 AM org.eclipse.jetty.util.log.Slf4jLog info INFO: Started SelectChannelConnector@localhost:9000 May 12, 2011 3:18:09 AM org.eclipse.jetty.util.log.Slf4jLog info INFO: started o.e.j.s.h.ContextHandler{,null} Server ready... *** The method about to be invoked by the CustomInvoker is named ---> getCustomerByID *** invoking getCustomer, Customer id is: 123 *** The method about to be invoked by the CustomInvoker is named ---> getOrder *** invoking getOrder, Order id is: 223 invoking getProduct with id: 323 *** The method about to be invoked by the CustomInvoker is named ---> getOrder *** invoking getOrder, Order id is: 224 invoking getProduct with id: 324 *** The method about to be invoked by the CustomInvoker is named ---> getOrder *** invoking getOrder, Order id is: 225 invoking getProduct with id: 325 *** The method about to be invoked by the CustomInvoker is named ---> updateCustomer *** invoking updateCustomer, Customer name is: Mary *** The method about to be invoked by the CustomInvoker is named ---> addCustomer *** invoking addCustomer, Customer name is: Jack Server exiting S:\cxf\distribution\src\main\release\samples\jax_rs\basic> I thought that the firewall and administrative settings on this Windows operating system would prevent me from printing this, but it turns out that I was incorrect about that. Client output with refactoring: Also, so that you can see the results of the refactoring that I mentioned, I have also included the client output here: mvn -Pclient [INFO] Scanning for projects... ... [INFO] --- exec-maven-plugin:1.2:java (default) @ jax_rs_basic --- Sent HTTP GET request to query customer info http://localhost:9000/customerservice/customers/123 123John Sent HTTP GET request to query sub resource product info http://localhost:9000/customerservice/orders/223/products/323 pro duct 323323 Sent HTTP GET request to query sub resource product info http://localhost:9000/customerservice/orders/224/products/324 pro duct 324324 Sent HTTP GET request to query sub resource product info http://localhost:9000/customerservice/orders/225/products/325 pro duct 325325 Sent HTTP PUT request to update customer info Response status code: 200 Response body: Sent HTTP POST request to add customer Response status code: 200 Response body: 124Jack S:\cxf\distribution\src\main\release\samples\jax_rs\basic> This was the output from the code that I showed, or at least approximately. I mention this because in my most recent iteration of changing the Client, I have been printing the url contents and url headers explicitly. This helped me figure out more about what seems to be the equivalence of an HTTP GET Request and a simple openURLConnection to, what else, a url. Ryan
Re: Basic Http Demo and the refactoring that I did, in the course of figuring out how it worked.
In the paragraph, with the hyperlink to the jaxrs demo, I said this: --- The client opens a printStream that is associated with the connection, and from that connection the client obtains the return information that would normally be associated with a GET request. It may be that since the only @Path in CustomerService with "/customerservice/customers/{id}" is the GET method, that the service automatically just queries that @Path and assumes a GET request, since that method is annotated with the @GET annotation. If you annotated it with more than one HTTP RequestType, I am unsure what would happen at the moment. That said, here is the refactoring part of the code. --- However, I found this, in a stack trace: --- May 12, 2011 4:29:04 AM org.apache.cxf.jaxrs.utils.JAXRSUtils findTargetMethod WARNING: No operation matching request path /customer/123 is found, HTTP Method : GET, ContentType : */*, Accept : text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,. --- Apparently the findTargetMethod(?); method named above takes care of selecting the HTTP method, at least in this case, based upon what url is received. But I was right, no explicit GET method is sent, the application simply selects, based upon input, which method to assume, or use. Ryan
Re: Basic Http Demo and the refactoring that I did, in the course of figuring out how it worked.
Cheers for the suggestion. Ryan On Thu, May 12, 2011 at 4:47 AM, Sergey Beryozkin wrote: > Hi Ryan > > On Thu, May 12, 2011 at 10:42 AM, Ryan Zoerner > wrote: > > In the paragraph, with the hyperlink to the jaxrs demo, I said this: > > > > > --- > > > > The client opens a printStream that is associated with the connection, > and > > from that connection the client obtains the return information that would > > normally be > > associated with a GET request. It may be that since the only @Path in > > CustomerService > > with "/customerservice/customers/{id}" is the GET method, that the > service > > automatically > > just queries that @Path and assumes a GET request, since that method is > > annotated with > > the @GET annotation. If you annotated it with more than one HTTP > > RequestType, I am unsure > > what would happen at the moment. That said, here is the refactoring part > of > > the code. > > > --- > > > > > > However, I found this, in a stack trace: > > > --- > > May 12, 2011 4:29:04 AM org.apache.cxf.jaxrs.utils.JAXRSUtils > > findTargetMethod > > WARNING: No operation matching request path /customer/123 is found, > > HTTP Method : GET, ContentType : */*, > > Accept : > text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,. > > > --- > > > > Apparently the findTargetMethod(?); method named above > > takes care of selecting the HTTP method, at least in this case, based > upon > > what url is received. But I was right, no explicit GET method is sent, > the > > application simply selects, based upon input, which method to assume, or > > use. > > > No, HTTP method is always sent by the client code, it is just in your > case, when you do > url.openStream() or similar, it's defaulted to GET. > > By the way, enabling the FINE logging level on the server side will > let you see more details about the selection process > > Cheers, Sergey > > > Ryan > > >
Questions regarding the implementation of a 2-endpoint Customer and CustomerService CXF JAX-RS web application
Sergey, I have the following question regarding the project. - - Customer: - Per-request resource: Does Customer store Customers? By what mechanism does Customer return Customers? Constructor (overloaded)? FactoryMethod? Constructor w/necessary calls to setName and setID? What methods should I expose?: Overloaded or non-overloaded constructor? Manipulate name and id, or do not manipulate name and id? (Get and Set) Should I keep a list of Customers, perhaps in class CustomerStorage? Do you want a CustomerFactory and a Customer object? - - CustomerService: Does it store the customers or does Customer store the customers, (or both)? Does anything store the customers? Does customerService call Customer to retrieve Customers from storage? Does it call Customer to generate Customers fresh each time? Does it store Customers that it retrieves? For how long does it store the complete list of Customers that it retrieves. Is there anything such as a 'request-set' of Customers, s.t. (such that), you can display a list of Customers retrieved in one request session? By what means does CustomerService instantiate xml? Does it instantiate the xml? With JAX-WS, there is WSDL and WS-import. If I create a Customer Interface; if I store it on the Customer Endpoint by what mechanism can I obtain a method-stub representation of the class, on this Endpoint, s.t. I can instantiate the class and use getters and setters? - - Because I thought that Customer must store Customers, what I created was: +customerService.customer.classes+ -CustomerFactoryImpl.java -CustomerImpl.java -CustomerStorageImpl.java +customerService.customer.interfaces+ -Customer.java{ generateNewCustomerInstance() } -CustomerFactory.java { overloaded constructor,set[...],get[...] } -CustomerStorage.java { add, get, update, delete } +customerService.jaxrs.client -Client.java { sends commands to endpoints and receives responses } +customerService.jaxrs.client.xmlResources -add_customer.xml -customer_list.xml { list of Customers } -update_customer.xml +customerService.jaxrs.customerGenerationAndStorage -CustomerService.java { uses add, get, update, and delete to manage CustomerStorage.java } -Server.java { consumes messages and produces responses } +customerService.jaxrs.customersListingService -CustomersService.java { makes calls to CustomerService, to instantiate or retrieve Customer instances, in the form of xml. I was envisioning being able to instantiate a CustomerFactory from within this code, and in such a way that it can be treated as though it were contained in code that is in another package in my workspace, in eclipse, with this package. Somehow to create code s.t., CustomerFactory c = new ... /** * I want this to return a new instantiated * Customer that has come in from the other * service, by means of an xml transmission. * * Presumably, you could import the FactoryImpl and * extend it by adding some helper class to the * constructor which would transform an xml * representation to an Object representation. * Presumably, that class would be a part of cxf. * * I would like, also, for the environment to be * able to locate the URI of the resource as though * it were simply another package in a packaged * web archive. This, because you want the * FactoryImpl to not implement any web methods * what-so-ever. I guess, ideally, you would say * * @InjectWebMethod("/URI-of-method") * private CustomerFactory c; * * and this would be instantiated in the constructor, * but declared from within class-scope. And the * ann
Re: Questions regarding the implementation of a 2-endpoint Customer and CustomerService CXF JAX-RS web application
Hi Sergey, You mentioned that Customer should display a single customer. Does CustomerService instantiate that Customer? By what mechanism? I created this class to try and get around that problem. In the old demo, Customers were instantiated in CustomerService, however, if you have CustomerService being called by Customer to get its Customer to display, does that make sense to you? The server would call getCustomer and the createCustomer method would act like init() on an individual call basis. I may have questions about your response that I just read, but I am too tired right now to develop them. public Customer() { @Path("/name/none/id/none/") public Customer getCustomer() @Path("/name/{name: [a-zA-Z]+}/id/none}") public Customer getCustomer(@PathParam("name") String name) @Path("/name/none/id/{id: [0-9]+)") public Customer getCustomer(@PathParam("id") long id) @Path("/name/{name: [a-zA-Z]+}/id/{id: [0-9]+)") public Customer getCustomer(@PathParam("name") String name, @PathParam("id") long id) @GET private Customer createCustomer() @GET private Customer createCustomer(String name) @GET private Customer createCustomer(long id) @GET private Customer createCustomer(String name, long id) } --- Thank you, Ryan
Re: Questions regarding the implementation of a 2-endpoint Customer and CustomerService CXF JAX-RS web application
The full Customer.java class may be viewed here: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/customerservice/Customer.java
Re: Questions regarding the implementation of a 2-endpoint Customer and CustomerService CXF JAX-RS web application
Thank you for your answer. I'm sorry, I didn't see it before I posted the link. Ryan
Re: Server output as a result of the CustomInvoker and Client output after parameterization refactoring of Client, CustomerService, and Order
Here are the links to the CustomerService.java and Client.java files that I have in my development environment. Also, here are the output files from the client and the server. You can see from the header that the 400 status code happens fine. I think that the xml error might be as a result of cxf catching the exception, but I think that Jetty may be throwing up the xml parsing error, on its own, for some reason. http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/Client.java http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/CustomerService.java http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/output.client http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/output.server http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/output.client.400_status Ryan
Re: Server output as a result of the CustomInvoker and Client output after parameterization refactoring of Client, CustomerService, and Order
Hi, Here is a link to Server.java, CustomerResourceProvider.java, CustomInvoker.java, and, CustomExceptionMapper.java: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/Server.java http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/CustomResourceProvider.java http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/CustomInvoker.java http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/CustomExceptionMapper.java In addition, I found out that the browser is also receiving the 400 status code. At minimum, due to expecting text/xml, when it gets a blank screen, it says that it cannot parse it. Here is the response to the browser, which was captured with a Firefox plugin called Http Response Browser 0.3: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/response.toBrowser.400_status https://addons.mozilla.org/en-US/firefox/addon/http-response-browser/ and here is what the response looks like when the browser prints a message in response to it: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/jaxrs_basic_http_demo/400_header_url_response_to_browser.png Have a great weekend also. Ryan
CustomerService Project
Hello all, I am in the middle of trying to get a JAX-RS Client/Server project to work. I am having trouble because I cannot figure out how to get my Customer class to find out about the sub-resource method located in a CustomerState class. I have tried assigning it to a resource provider. I have tried declaring Interfaces to both Customer and CustomerState, putting them in both the server and client folders. I have tried declaring CustomerState as a provider. I don't remember what else I tried, but I have been trying for approximately 4 hours now. I have looked everywhere, but the documentation implies that nothing more is necessary than to put an @GET on the method of choice and call that method from the class containing the @Path. I have thought about context injection, but don't know what to do. I do not have an explicit Application subclass. The JAX-RS api is sparse with comments. The sparseness of the spec in definitions and scope, leaves something to be desired also (at least for me). If you look here: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/customerservice/testing/ you can see the code. Here is the most recent error message from the Server: [INFO] [INFO] >>> exec-maven-plugin:1.2:java (default) @ jax_rs_basic >>> [INFO] [INFO] <<< exec-maven-plugin:1.2:java (default) @ jax_rs_basic <<< [INFO] [INFO] --- exec-maven-plugin:1.2:java (default) @ jax_rs_basic --- May 15, 2011 10:12:14 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher WARNING: No resource methods have been found for resource class java.lang.Class May 15, 2011 10:12:15 PM org.apache.cxf.endpoint.ServerImpl initDestination INFO: Setting the server's publish address to be http://localhost:9000/ May 15, 2011 10:12:15 PM org.eclipse.jetty.util.log.Slf4jLog info INFO: jetty-7.3.1.v20110307 May 15, 2011 10:12:15 PM org.eclipse.jetty.util.log.Slf4jLog info INFO: Started SelectChannelConnector@localhost:9000 May 15, 2011 10:12:15 PM org.eclipse.jetty.util.log.Slf4jLog info INFO: started o.e.j.s.h.ContextHandler{,null} Server ready... May 15, 2011 10:12:24 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher WARNING: No resource methods have been found for resource class java.lang.String May 15, 2011 10:12:24 PM org.apache.cxf.jaxrs.JAXRSInvoker invoke SEVERE: No subresource locator found for path / May 15, 2011 10:12:24 PM org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse WARNING: WebApplicationException has been caught : no cause is available May 15, 2011 10:12:24 PM org.apache.cxf.jaxrs.utils.ResourceUtils checkMethodDispatcher WARNING: No resource methods have been found for resource class java.lang.String May 15, 2011 10:12:24 PM org.apache.cxf.jaxrs.JAXRSInvoker invoke SEVERE: No subresource locator found for path / May 15, 2011 10:12:24 PM org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse WARNING: WebApplicationException has been caught : no cause is available Any suggestions that you might have would be helpful. Here is the client code message: Sent HTTP GET request to query customer info url: http://localhost:9000/customer/state/ getHeaderField(0) [HTTP/1.1 404 Not Found] getHeaderField(1) [Mon, 16 May 2011 03:12:24 GMT] getHeaderField(2) [0] getHeaderField(3) [text/xml] getHeaderField(4) [Jetty(7.3.1.v20110307)] getContent: [INFO] [INFO] BUILD FAILURE [INFO] This works fine and dandy when I return a CustomerState Object from a field belonging to Customer, but the problem is, I really don't need a subresource method to return it. I think, although, at the time, I had a method declared called getCustomerState which returned the String from CustomerState, and I had it annotated with @GET. If I removed that, perhaps the other configuration wouldn't work also? Here was the message for that, from the Client: Sent HTTP GET request to query customer info url: http://localhost:9000/customer/state/ getHeaderField(0) [HTTP/1.1 200 OK] getHeaderField(1) [Mon, 16 May 2011 02:45:13 GMT] getHeaderField(2) [14] getHeaderField(3) [text/html] getHeaderField(4) [Jetty(7.3.1.v20110307)] getContent: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@1d1cdf7 *** __INSTANTIATED *** __INSTANTIATED *** The last three lines in the output correspond to these methods: System.out.println(((InputStream) url.getContent()).toString()); in = (InputStream) ur
Re: CustomerService Project
I mentioned that it works fine when done a certain way, but unfortunately, it works just fine without the @GET annotated method, without the @GET and without the method. Thanks, Ryan http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/customerservice/testing/unfortunately_works_fine_like_this/
some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner
I have some thoughts that I wanted to post to the dev list. Here they are: The RP will need to choose between lifecylces, possibly just selecting which existing cxf resourceProvider to choose, based upon annotation. The annotations may be found in the class resource info object, obtainable from the JAXRSService. Look up the EJB annotations and find out which EJB-lifecycle this class is subscribing to, then call the appropriate cxf RP. We will need to know which cxf RP, at the time of SF.setRP(EJB_RP); "EJB_RP" will call Singleton- or per-request- RP's, or some other, based on @'s. Exceptions: if thrown, what does cxf normally do with it? Does this vary between exceptions. If cxf always passes it off to the server container, then that is just fine. Need to get a list of all possible exceptions throwable and map them to exception responses, via customExMapper? will we need to have the exceptionMapper called automatically, so that the user doesn't have to remember to set it, just to have cxf do what user should take for grantd? What else do ejb annotation's do, besides dictate lifecycle? Does cxf app-lifecycle function handle, or need to handle any of these functions? Does java normally handle them? Does a server typically handle any of them? ClassScanner idea: --- Ok, so in terms of lifecycle management, when an ejb class is declared as a root resource, it will need to be handled by a given resourceProvider. This will handle the various lifecycles that EJB's provide. When the setResourceClass is called on an ejb-annotated root resource, cxf should have a mechanism in place to recognize the ejb annotation, as-such, by looking it up in a list, and force cxf to use the custom resource provider. The annotations are part of the information that goes into the classResourceInfo object that resides with the JAXRSServiceFactory. There may be some way to listen for the creation of the classResourceInfo object, and then use it, at that time, to decide whether the customResourceProvider should be the default. --- Thank you. Ryan
Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner
This is what I had in mind for an RP constructor: Incidentally, EJB annotations show up in the cri. under ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j]. h.type.name and ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].h.memberValues.table[k].key and ClassResourceInfo.elementData[i].resourceClass.declaredAnnotations.table[j].h.memberValues.table[k].value as an example, I annotated Customer.java with @EJB and find: interface javax.ejb.EJB @javax.ejb.EJB(beanName=, mappedName=, beanInterface=class java.lang.Object, description=, name=) within the cri associated with serverF.serviceF.classResourceInfos... public class JAXRS_EJBResourceProvider implements ResourceProvider { enum EjbLifecycle { STATELESS, STATEFUL, SINGLETON } private Object resourceInstance; public JAXRS_EJBResourceProvider(Object o, JAXRSServerFactoryBean sfb) { if( isEJB(o, sfb) ) { EjbLifecycle ejbLifecycle = getLifecycleFromAnnotation( o, sfb ); if( ejbLifecycle == EjbLifecycle.STATELESS ) { resourceInstance = delegateTo( STATELESS_delegatee ); } else if( ejbLifecycle == EjbLifecycle.STATEFUL ) { resourceInstance = delegateTo( STATEFUL_delegatee ); } else if( ejbLifecycle == EjbLifecycle.SINGLETON ) { resourceInstance = delegateTo( SINGLETON_delegatee ); } else { throw new impossibleThingHappenedException(); } } else { return; } return; } }
Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner
Of course, resourceInstance should probably be resoureceProvider. Then you can just call the variable provider from methods where necessary. Ryan
Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner
Also, I suppose that you could just use AnnotationUtils on "o" in the formal params and then find out isEJB() and ejbLifecycle from that. Ryan
Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner
and btw, I didn't intend any pun on your initials. Ryan
Re: some thoughts that I wanted to post, in regards to RP, CRI, Exceptions, and a class scanner
you will note that nabble mangled the ); in my email, which is what caused me to think of this. Ryan
JAXRS EJBInvoker
It has been a while since I have written to the dev list, but I am working on putting an JAXRSEJBInvoker together. The naive implementation (in this case, that means rough draft), consists of taking JAXRSInvoker, replacing all instances of that word with EJBInvoker, extending AbstractInvoker, and adding in the code from the EJBInvoker found in geronimo. The main key difference between JAXWSInvoker and EJBInvoker is that EJBInvoker hands actual invocation responsibilities off to the EJB container instead of to java method reflection. For the invoke method with 4 params, in AbstractInvoker, the method can be directly replaced by the methods in EJBInvoker. The only place where an actual invocation call is made is in that method. The entire method is devoted to getting ready for the call to performInvocation. So that's what I've done so far, is merge EJBInvoker into JAXRSInvoker. I now have had trouble building openEJB, however, I remember easyBeans building fine. Also, I see that easyBeans is deployable on Jetty. I am uncertain whether or how declaring an EJB container resource, using ?ResourceProvider? will cause jetty to deploy the endpoint through that container, instead of through the Servlet container that it had been using in the jaxrs examples (i think). Since cxf abstract invoker is used, it may be that, without adding all of the additional code from geronimo to cxf, it might be deployable anyway, as EJB container, using jetty to deploy ejb resource ? I am uncertain whether testing this invoker in this way is best, but it seems that deploying easyBeans by converting the jaxrs basic http example to EJB might be the simplest way to test this. It all goes back to what information do you need to pass in to call the method? Where are you passing it? What are you getting back? Where is it going? That is all that the JAXRS Invoker was taking care of, as far as I know, other than maintaining some record (stack) of contextual information (and I'm not sure how long that history is saved, but from method call to method call is my guess). The only thing that the EJBInvoker does is retrieve a different set of contextual information and defer to a different container. It is now 11:13 which is sort of late for me, so I just listed what I think I know; I did not publish a formal paper here. However, I would like to know whether it sounds like I'm on the right track. Thanks, Ryan
Re: JAXRS EJBInvoker
Here is a link to the rough draft: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/EJBInvoker/EJBInvoker.java
Bean Invoker, Proxy, EasyBeans EJB Remote Home proxy for remote calls
Sergey, I have seen the Bean Invoker in cxf. I have just come across the class EJBHomeCallFactory in EasyBeans. I am wondering if it might suit our needs to use this, BeanInvoker, and make BeanInvoker extend JAXRSInvoker. What do you think? If not, I am currently putting together a resourceProvider which selects between the Stateless, Stateful, Singelton, EJB Factories in Easybeans, and returns a resource from whichever state we have for this RP. I am passing in the cri and will find out whether the bean is stateful, stateless, etc., and then set an enum constant with that value, which value will determine which factory is selected. What do you think about the idea? Thank you. Ryan Zoerner
Re: Bean Invoker, Proxy, EasyBeans EJB Remote Home proxy for remote calls
When I was debugging the jax-rs example, I placed an @EJB annotation in my Customer class and it showed up in the annotations in cri. Hence, any lifecycle-defining annotations would show up also?
Re: Bean Invoker, Proxy, EasyBeans EJB Remote Home proxy for remote calls
Sergey, I might be able to prove you wrong about which annotations are scanned from the class for the cri? I had evidence to the contrary. Also, it might be just fine to return the factory, as in this resourceProvider here: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/EJB/EJBResourceProvider.java because the factory seems to have a localMethodCall class, which gives the bean instance to the java.lang.reflect.Method.Invoke(..) method, along with method params. How it knows which method, I couldn't see just yet. If that is the case, then I know how to change the rough draft of the EJBInvoker to allow for this other method of invocation. Thanks, Ryan
Re: Bean Invoker, Proxy, EasyBeans EJB Remote Home proxy for remote calls
Hi Sergey, >>The fact you have seen EJB-related annotations being associated with a >>given CRI instance in debugger simply confirms the fact JVM retains >>them. But the sole responsibility of CRI is to model a JAX-RS root >>resource or subresource. It can not deal with with how a given >>resource is provided (via EJB, or something else) I converted this feature of the resourceProvider to annotation-based recognition, using methods of 'Class'. I think that this equates to the class-scanning feature that you had recommended. Because the EasyBeans StatelessSessionBean seems to be the only one produced by the invoker factory, it seemed good to decide between the four that are possible. At the same time, the presence of an EJB Lifecycle is also verified for the class's annotations. Because there are separate factories for each lifecycle, one of them has to be decided upon somehow and the jonas-easybeans-cxf code does not seem to do so. here are the links: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/EJB/EJBResourceProvider.java http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/EJB/EJBLifecycle.java Thanks, Ryan
Re: Bean Invoker, Proxy, EasyBeans EJB Remote Home proxy for remote calls
Also, for academic interest's sake, here is, to me, a novel idea for restructuring a class, which implements one subclass for each refactored method, each of which contains all submethods: http://pages.cs.wisc.edu/~zoerner/downloads/dev/samples/EJB/idea_to_simplify_a_class_for_readability/
Re: Write attachment on client side
Perhaps you are not familiar with ASCII http://michaelgoerz.net/blog/2008/09/ascii-table/ascii.gif -- View this message in context: http://cxf.547215.n5.nabble.com/Write-attachment-on-client-side-tp4531228p4539233.html Sent from the cxf-dev mailing list archive at Nabble.com.
Re: Write attachment on client side
Nudge, nudge. Wink, wink. Know what I mean? -- View this message in context: http://cxf.547215.n5.nabble.com/Write-attachment-on-client-side-tp4531228p4540243.html Sent from the cxf-dev mailing list archive at Nabble.com.
Re: Bean Invoker, Proxy, EasyBeans EJB Remote Home proxy for remote calls
Hi Sergey, Yes, I've been looking at that package and exploring the same issues. I see that there is an EasyBeansCXFBootstrap. I am unsure whether the bootstrap is what is directly instantiated by a server such as Jetty or Tomcat. I found it, tracing constructor calls out from the CXFEJBWebserviceEndpoint. I will continue to look at Jonas-cxf and try to gain a more comprehensive understanding. Thanks. Ryan
Re: Bean Invoker, Proxy, EasyBeans EJB Remote Home proxy for remote calls
Correction, I found it searching for which class instantiates CXFEJBWebserviceEndpoint, which class instantiates that, etc. Ryan
Re: Write attachment on client side
Perhaps you didn't ask on the user list. -- View this message in context: http://cxf.547215.n5.nabble.com/Write-attachment-on-client-side-tp4531228p4549012.html Sent from the cxf-dev mailing list archive at Nabble.com.
Re: Bean Invoker, Proxy, EasyBeans EJB Remote Home proxy for remote calls
Thank you. Ryan Zoerner On Mon, Jul 4, 2011 at 4:40 AM, Florent BENOIT wrote: > Hi, > > If you need details about EasyBeans/CXF integration, you may also ask on > easybe...@ow2.org mailing list > I can also answer on this ML ;-) > > Regards, > > Florent > > > On 07/01/2011 04:40 PM, Sergey Beryozkin wrote: > >> Hi Ryan >> >> On Fri, Jul 1, 2011 at 2:36 PM, Ryan Zoerner >> wrote: >> >> >>> Hi Sergey, >>> >>> Yes, I've been looking at that package and exploring the same issues. I >>> see >>> that there is >>> an EasyBeansCXFBootstrap. I am unsure whether the bootstrap is what is >>> directly >>> instantiated by a server such as Jetty or Tomcat. I found it, tracing >>> constructor calls >>> out from the CXFEJBWebserviceEndpoint. >>> >>> I will continue to look at Jonas-cxf and try to gain a more comprehensive >>> understanding. >>> >>> >>> >> Sounds good. Having a better appreciation of how that works is a key IMHO. >> >> Cheers, Sergey >> >> >> >>> Thanks. >>> >>> Ryan >>> >>> >>> >> >> >> >> > >
EJBInvoker, progress, observations, questions about EJB creation organization, other various questions.
Hi Sergey, I am wondering about the 'finally' block in the 'public Object invoke(Exchange exchange, Object request)' method of the JAXRSInvoker class. For me, it is line numbers: 113-139. These lines call the resourceProvider to release the object instance in certain cases. Is this something that we can exclude from the JAXRSEJBInvoker? Should the bean manage all of its lifecycle based on the annotation or lifecycle-type (as when declared in xml)? In the InvokerFactory model, it releases the instance. In that model, the invoker plays the role of the resourceProvider by containing the Factory. I went through the CXFEasyBeansInvoker from easybeans, and compared it with the Jonas version, by commenting each line or group of lines with their location in the Jonas/CXF version. I think that now, we need to: Get the bean instance from the factory and use java.lang.reflect.Method to invoke the method. After the method is invoked, the bean is released. The InvokerFactory does that by way of the Invoker in the Jonas model. The Jonas model has JAXWSInvoker (with no invoke methods) managing other aspects of cleanup during invocation. The EasyBeansCXFInvoker invoke(w/ 4 params) method, contains, all the way down to the exceptionHandling, the essentials of the EasyBeans portion of the invocation. The remainder is common to AbstractInvoker. Right now, then, I am looking at JAXRSInvoker. If serverFactory.setResourceClass() won't work, how will we adjust it to allow for @Stateless, @Stateful, etc. annotations? I think that it currently throws an exception for an unknown annotation. Also, I've noticed that the JContainer3 has a method for creating a factory for itself. I am wondering about passing in factories. How will the factories be created? How will the IDeployable be created? I was thinking about passing that in to the RP and creating the factories that way, but maybe it would be better, somehow, to create the bean instance somewhere.. where??, and pass that into the RP, which can then invoke the JContainer3's start() method, which calls createBeanFactories(), which calls both createMessageDrivenBeanFactory and createSessionBeanFactory. So, passing the bean in, seems to be the, now, preferred, method, however, where and how is the bean going to be created? Do we declare it as a resourceClass? It does not seem to be focused on as being a class, in Easybeans, rather, the focus seems to be that of the entire deployable package or folder or archive. So, I am wondering what you think about the idea of passing the bean in and using it to start the factory, but am concerned about how cxf proposes to deploy this container? Should I be looking at the CXF/Jetty (such as cxfServlet) interface and finding out how the bean should be deploying through jetty? or are we just going to have the bean resource, lifecycle managed by factory, sitting alone as accessible through a servlet? I think that I am close to having the invoker finished. My main concern is how are we going to get the beans instantiated so that I can test them as being deployed? My main concern with the invoker is, what parts of JAXRSInvoker correspond to sf.declareResourceClass? If that method will not run for EJB annotations, what will become of cri and ori? Will we change declareResourceClasses? Will it be necessary? I just wanted to update you on my progress. The class-scanner in the RP might be moved out of the RP into whatever class creates an EJB IDeployable and packages it into a bean, returing a factory instance. Thanks, Ryan
Re: EJBInvoker, progress, observations, questions about EJB creation organization, other various questions.
Hi Sergey, I have tested @Stateless in CustomerService.java, from the http basic example in jaxrs-samples. The annotation appears in the list in ServerFactory.Service.ClassResourceInfos[].ResourceClass.annotations. Therefore, sf.setResourceClasses does not interfere with the annotation being processed, but I had seen it throw an exception before, for some unknown reason. The point that I was making before is that CXFEasyBeansInvoker is precisely the difference between cxf-easybeans and CXF-JAXWS-easybeans. Also, the jonas version, which was the second group mentioned in the last "between" statement, does the Invoker and InvokerFactory. The Invoker does not do invoker it just extends jaxwsAbstractInvoker and gets and releases resource. Perhaps, similar to RP. I think that there is no RP in the Jonas model. The jonas model keeps a factory field that is instantiated at construction time, in the InvokerFactory. The invoker factory actually manages the specific releasing of the pool gotten object. So. Basically, I think that the InvokerFactory and Invoker from that model can be refactored out into RP-- refactored partially. Second, if the Invoker extends JAXRS Invoker, it would precisely be the EasyBeans version of the Invoker, but with factory-pool model, and with JAXRS instead of JAXWS. So, for starters, that is what I would recommend to myself as doing next. Then, if it needs to be adjusted (JAXRSInvoker) then that would be the other step. Perhaps it will now be doing things that are not needed. Then, in order to create the EJBInstance, it would be nice to have some create EJB Instance method, as described before, which would take things like the web.xml file as params, and then create the IDeployable, create the EJBInstance, and from that JContainer3, create the appropriate factory, since the container already automatically selects which factory to instantiate. That factory can either sit in RP, which is where these methods might go, or possibly as some EJBPackageCreationUtility class that is called by RP, or perhaps, factory could be passed to InvokerFactory, but I think that because JAX-RS, you might want to keep the RP model. So, there is my synopsis on where the answer is, and if permission, I will create the Invoker in the steps that I described here. Thanks again, Ryan
Re: EJBInvoker, progress, observations, questions about EJB creation organization, other various questions.
Hi again Sergey, I noticed that there is a CXFResourceInjector class, in Jonas, which does annotation processing, presumably on an ejb-annotated resource class. However, this may be only for integration of cxf with Jonas. Because the easybeans version of the invoker is exactly the same, it seems that easybeans, is, itself, deployable on jetty and that some of these supporting classes in Jonas might not be necessary. Also, the Invoker and InvokerFactory, within Jonas are instantiated in a single line in EasyBeansJaxWsServiceFactoryBean, which corresponds to the JAXRSServer or JAXRSService Factory approximately, so you can see that the invoker is treated in the same way as in CXF JAXRS. The resource injection is approximate to AbstractResourceInfo processing, I think. Thanks, Ryan
Re: EJBInvoker, progress, observations, questions about EJB creation organization, other various questions.
For reference purposes, here is the call hierarchy up from EasyBeansInvokerFactory: EasyBeansInvokerFactory EasyBeansMethodInvoker EasyBeansJaxWsServerFactoryBean LifeCycleCallback (in Jonas and in easybeans-cxf) (in easybeans-cxf) CXFConfigurationExtension (in Jonas) CXFConfigurationExtension CXFConfigurationExtension (in easybeans only) EasyBeansCXFBootstrap this class extends EmbeddedBootstrap, has no constructor, so class is only a name to call and an additional method for the EmbeddedBootstrap. org.ow2.easybeans.server.war.EasyBeansContextListener loads EmbeddedBootstrap class. org.ow2.easybeans.cxf.EasyBeansCXFListener loads org.ow2.easybeans.cxf.EasyBeansCXFBootstrap. No further info could be found except that EasyBeansCXFListener is described as: * Listener class which is notified of lifecycle events. It allows to start * EasyBeans at startup and stop it at the end. It is a contextListener that has a method -- getBootstrapClassName() -- which returns the bootstrap class to load. It may be that this class is called by Jetty. --Ryan
Re: EJBInvoker, progress, observations, questions about EJB creation organization, other various questions.
Everything below EasyBeansJaxWsServerFactoryBean is available in easybeans without the aid of Jonas. Ryan
Re: EJBInvoker, progress, observations, questions about EJB creation organization, other various questions.
>Do you agree or do you still see the need to have custom >JAXRSEJBInvoker & custom EJBResourceProvider ? I'm not sure what >JAXRSEJBInvoker will do ? Then, in order to create the EJBInstance, it would be nice to have some create EJB Instance method, as described before, which would take things like the web.xml file as params, and then create the IDeployable, create the EJBInstance, and from that JContainer3, create the appropriate factory, since the container already automatically selects which factory to instantiate. That factory can either sit in RP, which is where these methods might go, or possibly as some EJBPackageCreationUtility class that is called by RP, or perhaps, factory could be passed to InvokerFactory, but I think that because JAX-RS, you might want to keep the RP model. >Do you mean Invoker asks InvokerFactory to manage the lifecycle ? Yes, invoker calls create and release in InvokerFactory. So the instance from pool management specifically happens in Invoker Factory. >Do you think JAXRSEJBInvoker should extend JAXRSInvoker yes. >and decorate >the invocation with something similar to what >EasyBeansCXFInvoker does ? Ok. So, EasyBeansCXFInvoker copies stuff from the AbstractInvoker that it extends http://pages.cs.wisc.edu/~zoerner/downloads/dev/referenced_in_mailing_list_question/test_easybeans_invoke.java You can see that in the invoke method, until the exception catching occurs, that all of the lines, with the exception of packaging the response into a list, are taken exactly from either the InvokerFactory, or the AbstractInvoker, so, because Jonas InvokerFactory only extends, for invocation(..) method calls from AbstractInvoker (including performInvocation), I would like to possibly refactor, as just mentioned, Invoker and InvokerFactory into RP (factory) provider and Invoker, with outside method to construct EJB packageable resource from component items, such as class source, web.xml file, etc. EJBInvoker would then extend JAXRSInvoker. RP would be settable as RP to JAXRSServerFactoryBean. If you disagree, obviously the final code organization policy is up to Apache and yourself, not me. >Don't worry about the class scaner for now, please try to understand >how EasyBeans sets up a CXF JAX-WS endpoint and follow the same >process... the easybeans package is called easybeans-cxf-extension, am I correct that the easybeans bootstrap or cxfListener should be registered as an extension? Perhaps I could set up an easybeans extension in cxf and try to deploy by way of cxf jaxws serverFactory, or equivalent? I would need help verifying correctness of JAX-WS Java code and xml config files and namespaces, and perhaps help with Maven setup, such as ?plugin setup? I think to set up a file without a parent would be best (if we go this direction) and to place all dependencies in that file. I sent 4 other messages btw., in case you didn't read them. Thanks, Ryan -- View this message in context: http://cxf.547215.n5.nabble.com/EJBInvoker-progress-observations-questions-about-EJB-creation-organization-other-various-questions-tp4555258p4563210.html Sent from the cxf-dev mailing list archive at Nabble.com.
Re: EJBInvoker, progress, observations, questions about EJB creation organization, other various questions.
There was a bit of a typo: "because Jonas InvokerFactory only extends, for invocation(..) method calls from AbstractInvoker (including performInvocation)" because Jonas InvokerFactory ( the only other code referenced in EasyBeansCXFInvoker.invoke(4 params) ) extends AbstractInvoker for all practical purposes, in terms of calls to invoke(..), performInvocation, and related sub-methods of AbstractInvoker, (it seems good to extend JAXRSInvoker with calls to AbstractInvoker rather than synthesizing them into one invoke(4 params) method in EJBInvoker. Thanks, Ryan -- View this message in context: http://cxf.547215.n5.nabble.com/EJBInvoker-progress-observations-questions-about-EJB-creation-organization-other-various-questions-tp4555258p4563226.html Sent from the cxf-dev mailing list archive at Nabble.com.
Sergey: I've completed my Mid-term evaluation for GSoC.
Thanks, Ryan
Stateless EJB's and JAX-WS (no comment necessary)
There were only StatelessSessionBeans in the CXF factory because: === The client of a stateless session bean may be a web service client. Only a *stateless *session bean may provide a web service client view. === (page 40) ejb-3_0-fr-spec-ejbcore.pdf EJB Final Release Spec
Re: Stateless EJB's and JAX-WS (no comment necessary)
I'm not sure why this is. (in regards to the above specification detail). JAX-WS calls for support for sessions. The web service mechanism should easily allow for the identification of which session, before an instantiated (Client-facing) Business Interface implementing EJB bean is directly engaged by the Client request. ? Is this supposed to be StatelessSession "session delegators" only? They might mean here, by "view", that the rendering of the client-viewed data is not session dependent. (although session data might be dependent upon previous session data.) But what about Web Services that only return Session-specific data and do not render a client view at all? What if the data is a list of words that the client has uploaded in previous requests, across one session? Ryan
JAXRS EJB ResourceProvider and Invoker
I have come to the conclusion that the EJB, when supplied from the easybeans factory, can be assumed to be container managed by easybeans, provided that easybeans works properly. Any exceptions thrown by CXF, while processing the EJB should be managed by ExceptionMapper. Will such exceptions exist, that are not, inherently, cxf exceptions? Any exceptions thrown in the process of the EJB container management. Are they not handled by the EJB container? If they are propagated to CXF, then CXF can still handle. Because RP and Invoker simply return and release class instances, the same as in non-EJB cxf interaction, cxf processing should not be affected by what instance is being returned. (Any details of lifecycle management in JAXRSInvoker, or any subclasses, may need altering, but I doubt it, except that they may not take the proper steps to release an instance, if they do not do it through the RP. So any non-RP lifecycle management will need to delegate directly to the RP, possibly via the Invoker. The RP releases the instance via the factory.) The interceptors will go over the resource class, and will process based on JAX-RS and JAXB annotations. EJB annotations are not paid attention to. The main thing is that the correct class(to the interceptor) and instance(to the m.invoke(..) method) are supplied. Only @Stateless beans are acceptable beans for a webservice. In normal non-ejb jaxrs cxf usage, only the resource class is supplied by the invoker. The invoker-supplied class calls the remainder of the supporting classes. A question that I have is: what if these other classes are EJB classes. How will the EJB container know about these classes, when CXF is deploying the main @Stateless bean. Is it through a deployment descriptor? Here are links to the EJB CXF RP and Invoker, as I have them. There will be no need to decide which type of EJB Factory to use, such as Stateless, Stateful, etc. All webservice bean instances will be Stateless. http://pages.cs.wisc.edu/~zoerner/downloads/dev/Invoker_bundle/JAXRS_EJB_Resource_Provider.java http://pages.cs.wisc.edu/~zoerner/downloads/dev/Invoker_bundle/JAXRS_EJB_Invoker.java These files are not guaranteed to not be edited. I will not add future versions of them at some other address. The ExceptionMapper is quite simple to write, and for that reason, I haven't typed it up yet. Thanks, Ryan Zoerner (easybeans, I'm wondering if you know about lifecycle management of supporting EJB classes.) (thanks.)
Re: Google Summer of Code -- Integration of Apache CXF JAX-RS with EJB (addendum)
As an addendum, I am posting links to my work in data structures, the Java Server Faces basic app that I worked on, a css package, which I also worked on, and a build.xml ant file which takes care of WAR-ing an application. The JSF app isn't much, but I am pleased about my work in Data Structures and my subsequent A. The css package is particularly useable in dreamweaver, because of their pop-up selection menu for classes and ids. The ant file is generally useful. http://pages.cs.wisc.edu/~zoerner/downloads/code_classwork/data_structures/projects/ http://pages.cs.wisc.edu/~zoerner/downloads/code_personal/JSF/basic_login/ http://pages.cs.wisc.edu/~zoerner/downloads/code_personal/css/content2008_css_package/ http://pages.cs.wisc.edu/~zoerner/downloads/code_personal/ant/war/ If anyone throws anything at me... well. Thanks everyone for your help, Ryan Zoerner 08/19/2011 -- View this message in context: http://cxf.547215.n5.nabble.com/Google-Summer-of-Code-Integratio-n-of-Apache-CXF-JAX-RS-with-EJB-tp4290214p4717315.html Sent from the cxf-dev mailing list archive at Nabble.com.