Unable to return collections or arrays from JAX-WS Web Service - arrays

I found that I was unable to return collections from my JAX-WS Web Service.
I appreciate that the Java Collections API may not be supported by all clients, so I switched to return an array, but I can't seem to do this either.
I've set up my web service as follows:
#WebService
public class MyClass {
public ReturnClass[] getArrayOfStuff() {
// extremely complex business logic... or not
return new ReturnClass[] {new ReturnClass(), new ReturnClass()};
}
}
And the ReturnClass is just a POJO. I created another method that returns a single instance, and that works. It just seems to be a problem when I use collections/arrays.
When I deploy the service, I get the following exception when I use it:
javax.xml.bind.MarshalException - with linked exception:
[javax.xml.bind.JAXBException: [LReturnClass; is not known to this context]
Do I need to annotate the ReturnClass class somehow to make JAX-WS aware of it?
Or have I done something else wrong?

I am unsure of wheter this is the correct way to do it, but in one case where I wanted to return a collection I wrapped the collection inside another class:
#WebService
public class MyClass {
public CollectionOfStuff getArrayOfStuff() {
return new CollectionOfStuff(new ReturnClass(), new ReturnClass());
}
}
And then:
public class CollectionOfStuff {
// Stuff here
private List<ReturnClass> = new ArrayList<ReturnClass>();
public CollectionOfStuff(ReturnClass... args) {
// ...
}
}
Disclaimer: I don't have the actual code in front of me, so I guess my example lacks some annotations or the like, but that's the gist of it.

Related

How to test a MessageBox in wpf?

I'm going to do some unit tests and I am struggling with a MessageBox. I have a MessageBox that is showing a text and an "Ok" button in my code. When I trying to unit test the method that contains the MessageBox.Show("Text"), it pops up in the unit test, too, and I have to click "Ok" before it can pass through, which is a bad.
Does anyone know how to go around it? I think I need some kind of code that fakes this MessageBox and clicking "Ok", but I dont know how to do this. I'm a junior programmer, so please explain it as easy as you can ;) and gladly with some code examples.
This is my code for the MessageBox:
public void GetPopUpWithErrorMessage()
{
MessageBox.Show("Error Message", "text",
MessageBoxButton.OK);
}
Edit
I just realised that Fluent Assertions is used in the project. Does anyone know how to implement that in the test code? is it the same way as #thatguy showed?
You have to create a service that implements an interface that you can mock in your tests.
public interface IMessageBoxService
{
void ShowMessageBox(string title, string message);
}
public class MessageBoxService : IMessageBoxService
{
public void ShowMessageBox(string title, string message)
{
MessageBox.Show(message, title, MessageBoxButton.OK);
}
}
In the class where you use it, you would pass this service by its interface, e.g. in the constructor, so the class only knows its contract, but not its implementation.
public class MyClass
{
private IMessageBoxService _messageBoxService;
public MyClass(IMessageBoxService messageBoxService)
{
_messageBoxService = messageBoxService;
}
public void GetPopUpWithErrorMessage()
{
_messageBoxService.ShowMessageBox("text", "Error Message");
}
}
In the test class, you need to use a mocking framework like Moq that creates a mock object from an interface, which is just a stub that you can use to inject the behavior for any method or property that you use in your test.
In this example using NUnit and Moq, messageBoxService is created as a mock object that implements the IMessageBoxService interface. All methods do nothing unless you specify what they should do or return via Setup, but that is another topic. The last line shows how you could check if a sepcific method on the mock was invoked during the test.
[TestFixture]
public class MyClassTest
{
[Test]
public void MyTest()
{
var messageBoxService = Mock.Of<IMessageBoxService>();
var myClass = new MyClass(messageBoxService);
// ...your test code.
// Checks if the "ShowMessageBox" method in the service was called with any strings
Mock.Get(messageBoxService).Verify(mock => mock.ShowMessageBox(It.IsAny<string>(), It.IsAny<string>()));
}
}
Creating a service and an interface is not just useful for mocking, but also for separating view and logic, as you can extract the calling of a message box to a service which has an implementation hidden behind an interface. Moreover you can easily implement dependency injection via constructors.

Hystrix Javanica : Call always returning result from fallback method.(java web app without spring)

I am trying to integrate Hystrix javanica into my existing java EJB web application and facing 2 issues with running it.
When I try to invoke following service it always returns response from fallback method and I see that the Throwable object in fallback method has "com.netflix.hystrix.exception.HystrixTimeoutException" exception.
Each time this service is triggered, HystrixCommad and fallback methods are called multiple times around 50 times.
Can anyone suggest me with any inputs? Am I missing any configuration?
I am including following libraries in my project.
project libraries
I have setup my aspect file as follows:
<aspectj>
<weaver options="-verbose -showWeaveInfo"></weaver>
<aspects>
<aspect name="com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect"/>
</aspects>
</aspectj>
Here is my config.properties file in META-INF/config.properties
hystrix.command.default.execution.timeout.enabled=false
Here is my rest service file
#Path("/hystrix")
public class HystrixService {
#GET
#Path("clusterName")
#Produces({ MediaType.APPLICATION_JSON })
public Response getClusterName(#QueryParam("id") int id) {
ClusterCmdBean clusterCmdBean = new ClusterCmdBean();
String result = clusterCmdBean.getClusterNameForId(id);
return Response.ok(result).build();
}
}
Here is my bean class
public class ClusterCmdBean {
#HystrixCommand(groupKey = "ClusterCmdBeanGroup", commandKey = "getClusterNameForId", fallbackMethod = "defaultClusterName")
public String getClusterNameForId(int id) {
if (id > 0) {
return "cluster"+id;
} else {
throw new RuntimeException("command failed");
}
}
public String defaultClusterName(int id, Throwable e) {
return "No cluster - returned from fallback:" + e.getMessage();
}
}
Thanks for the help.
If you want to ensure you are setting the property, you can do that explicitly in the circuit annotation itself:
#HystrixCommand(commandProperties = {
#HystrixProperty(name = "execution.timeout.enabled", value = "false")
})
I would only recommend this for debugging purposes though.
Something that jumps out to me is that Javanica uses AspectJ AOP, which I have never seen work with new MyBean() before. I've always have to use #Autowired with Spring or similar to allow proxying. This could well just be something that is new to me though.
If you set a breakpoint inside the getClusterNameForId can you see in the stack trace that its being called via reflection (which it should be AFAIK)?
Note you can remove commandKey as this will default to the method name. Personally I would also remove groupKey and let it default to the class name.

Apex error: "Save error: Method does not exist or incorrect signature"

I'm currently learning apex (using the Force.com IDE), and I'm running into some trouble when writing a test for a custom controller.
The controller class is as follows:
public with sharing class CustomController {
private List<TestObject__c> objects;
public CustomController() {
objects = [SELECT id, name FROM TestObject__c];
}
public List<TestObject__c> getObjects() {
return objects;
}
}
and the test class is:
#isTest
private class ControllerTest {
static testMethod void customControllerTest() {
CustomController controller = new CustomController();
System.assertNotEquals(controller, null);
List<TestObject__c> objects;
objects = controller.getObjects();
System.assertNotEquals(objects, null);
}
}
On the objects = controller.getObjects(); line I'm getting an error which says:
Save error: Method does not exist or incorrect signature: [CustomController].getObjects()
Anyone have an idea as to why I'm getting this error?
A nice shorthand:
public List<TestObject__c> objects {get; private set;}
It creates the getter/setter for you and looks cleaner imo. As for your current issue, yes - it's hard saving code directly into production - especially with test classes in separate files.
Best to do this in a sandbox/dev org then deploy to production (deploy to server - Force.com IDE). But if you must save directly into production then I'd combine test methods with your class. But in the long run, having #test atop a dedicated test class is the way to go. It won't consume your valuable resources this way.

How to initialize local fields of a WCF proxy class on deserialization

In my Silverlight client I have a partial class created by setting a WCF reference. I've extended this class adding a few RelayCommand properties. I need to initialize these properties which I would normally do in the constructor. However it seems that the constructor is not being called, which I believe is a result of of VTS However I'm also unsuccessful in using the OnDeserialized attribute.
What is the prescribed way to initialize client side data members of a WCF class.
I've created a sample project and everything works as expected. If this code doesn't help - post your data contract and client code.
namespace SilverlightApplication3.ServiceReference1
{
public partial class SomeModel
{
public string ExtendedProperty { get; set; }
[OnDeserializing]
public void OnDeserializingMethod(StreamingContext context)
{
this.ExtendedProperty = "Ok";
}
}
}
Service method call:
var proxy = new ServiceReference1.Service1Client();
proxy.DoWorkCompleted += (s,e) => Debug.WriteLine(e.Result.ExtendedProperty); //Ok
proxy.DoWorkAsync();

Is possible in WCF service: method return IList<object> when object can be Person class?

Is possible in WCF service: method return IList when object can be Person class?
Ex: in IServiceContract.cs
[ServiceContract]
public interface IDAS
{
[OperationContract]
void DoWork();
[OperationContract]
List<object> GetAnyClass();
}
And class:
public class DAS : IDAS
{
public void DoWork()
{
}
public List<object> GetAnyClass()
{
List<Person> a = new List<Person>();
a.Add(new Person());
return a;
}
}
The problem at runtime is:
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error
Theoretically yes, although you need to tell the service that it might be expecting a Person object using the KnownTypeAttribute on your method.
[OperationContract]
[KnownType(typeof(Person))]
List<object> GetAnyClass();
I would really think twice about doing this in practice though - instead declare different method signatures for the objects you're expecting to return:
[OperationContract]
IList<Person> GetPeople();
[OperationContract]
Person GetPerson();
[OperationContract]
IList<Book> GetBooks();
[OperationContract]
Book GetBook();
etc.
It's supposed to be a contract, i.e. concrete, so if you suddenly change the type of class you return it can really mess the clients up.
Also in your example you were returning a concrete List class - this should be avoided, instead use either IList<> or Collection<>.
Yes it is possible, you need to update the reference in Visual Studio (or whatever you are using to generate the proxy class with) and change the collection type returned. There is an option in 'Configure Service Reference' and you can select Generic.List in there (right click your WCF service reference).
The mismatch is because you have changed your service on the server end and not got a new proxy. So change it to return a Generic.List and then regenerate using the steps in 1.
Hope that helps
Ryan
You can return an IList but it's definitly not a good approach to take.
When you expose your services you need people at the other end of the service to know what they are getting.
IList<Person> would be clearer for everybody that use the services or that code in the services.
If you need a method that can return different type of object just split them out in multiple operations.
IList<Person> GetPersons(...)
IList<Animal> GetAnimals(...)
My 2 cents.
Cheva (et al),
There is nothing stopping you from calling a single method to fill in the collection(s) you return from the service calls.
IList<Person> GetPersons(...)
IList<Animal> GetAnimals(...)
Both GetPersons() and GetAnimals() can certainly call an internal method e.g.
IList<Animal> GetAnimals(...)
{
// get list of objects of a given type
internalIList<Object> genericResults = GetItems(
ItemType.Persons|ItemType.Animals );
...
IList<Animal> results;
// convert to specific type
results = new IList<Animal>(genericResults);
return results;
}
That should work, but I didn't test it or anything. YMMV. ; )
-Scott

Resources