GWT different interface implementation for client and server - java

Assume that we've some interface my.gwt.shared.Facade in shared package of our GWT project (exists both server and client) and two implementation of it: class my.gwt.client.ClientFacadeImpl (exists only client) and class my.gwt.server.ServerFacadeImpl (exists only server).
Is there any way to write a piece of code or annotation that substitute ClientFacadeImpl in client side and ServerFacadeImpl in server side?

Thanks all for the answers and discussion. I've found simple and elegant solution for my needs.
So, I've interface my.gwt.shared.Facade and two classes: class my.gwt.client.ClientFacadeImpl and class my.gwt.server.ServerFacadeImpl.
interface Facade {
Map<Boolean, Facade> FACADES = new HashMap<Boolean, Facade>();
}
Now, we should fill you FACADES interface. This is done like that:
public class MyEntry implements EntryPoint {
static {
Facade.FACADES.put(true, ClientFacadeImpl.INSTANCE); // client side
}
And
#Startup
#Singleton
public class Initializer {
#PostConstruct
private void init() {
Facade.FACADES.put(false, ServerFacadeImpl.INSTANCE); // server side
// other things
}
}
Now, when I need to get appropriate Facade, I just write
Facade facade = Facade.FACADES.get(GWT.isClient());
Also in this case in map is only corresponding to server or client side implementation.
P. S. Goal of this question was to allow handling of some GwtEvents fired on client direclty on server and vice-versa. This solution removed large set of DTO (data transfer objects) and simplified code a lot.

There's no answer to your question other than "it depends". Or rather, of course there are ways of doing what you ask, but would you accept the tradeoffs?
Given that you tagged the question with dependency-injection, let's start with that. If you use a DI tool with GWT, it's likely GIN (Dagger 2 would work, but it's still under development). In that case, just use distinct modules for GIN client-side and Guice server-side that bind() the appropriate implementation.
For a few releases, GWT.create() can be made to work outside a GWT (client) environment (i.e. on the server side). You have to register a ClassInstantiator on the ServerGwtBridge as an alternative to the rebind rules from gwt;xml files. So you could have a <replace-with class="my.gwt.client.ClientFacadeImpl"> rule in your gwt.xml, and a ClassInstantiator returning a ServerFacadeImpl on the server side.
Finally, you can also use a static factory and replace it with a client-side specific version by way of <super-source>.
A last one, but I'm unsure whether it'd work: you could use an if/else using GWT.isClient(), and annotate your ServerFacadeImpl with #GwtIncompatible to tell the GWT compiler that you know it's not client-compatible.

Related

where to put the behaviour of DTOs ? Object vs Data structure clean code

Similar question was posted here Clean code - how to design this class?
I still don't find an answer though, I'm confused!
I read the book "clean code" too.He is saying in some part you shouldn't mix data structure/Object, whether data structure with no behaviour or an object with behaviour.
In my application we have Data tranfer objects which carry data from external services .These DTO have just data accessors and mutators. So I was considering them as Data structure type.
However Robert Martin is saying in his book that client.isMarried() is better than isMarried(client) I found this logical as isMarried function use attributes only from client class.. it is cleaner.
In many areas in my application we need some behaviour on a certain DTOs I'm confused where to put this behaviour.
We have made Utils classes that has business logic like
ClientUtils {
boolean isMarried(Client client) { ...}
String getCompleteName(Client client) { ...}
}
Should this go to the service layer ? even if these methods does not manipulate any thing else other than the input object It does not interact with another layer (DAL, services .. )
Since you can't change the Client class due to the external library constraint, I wouldn't extend it. I suggest making a ClientInfo wrapper class that "has a" Client member instead.
class ClientInfo {
private Client myClient;
public ClientInfo(Client c) {
myClient = c;
}
public boolean isMarried() { ...}
public String getCompleteName() { ...}
}
If you ask me, then Utils class just means you have a random static method lingering somewhere which contains actual business logic. Why not keep DTOs as DTOs, and create a ClientManager class that has isMarried method?
The ClientInfo approach that wraps the external object is another option, possibly driven by Domain Driven Security.

How to subclass SubethaSmtp SMTPClient class

I am trying to develop a simple SMTPclient for testing purposes using the SubethaSmtp client package. i want to use the SMTPClient class instead of the SmartClient class for more control but i have not been able to figure out how to write mail data using SMTPClient, the only OutputStream exposed to public or external subclasses is the one for sending commands, the ones for sending data (after sending the DATA command) is exposed only to classes in the same package (SmartClient).
am i missing something here? i would like to know how a direct subclass of SMARTClient can written to work around this problem.
Looks like you are correct, you cannot simply extend the SMTPClient and get access similar to the one that SmartClient has, being a same-package class.
At this point you can either:
1) Fork your own version of the app from https://github.com/voodoodyne/subethasmtp and do whatever the hell you like with it, or
2) Go all the way and implement your own version of SMTPClient, as the package protected SMTPClient.dotTerminatedOutput;, used by SmartClient.dataWrite() actually is just instantiated like so
...
this.rawOutput = this.socket.getOutputStream();
this.dotTerminatedOutput = new DotTerminatedOutputStream(this.rawOutput);
...

I can't unit test my class without exposing private fields -- is there something wrong with my design?

I have written some code which I thought was quite well-designed, but then I started writing unit tests for it and stopped being so sure.
It turned out that in order to write some reasonable unit tests, I need to change some of my variables access modifiers from private to default, i.e. expose them (only within a package, but still...).
Here is some rough overview of my code in question. There is supposed to be some sort of address validation framework, that enables address validation by different means, e.g. validate them by some external webservice or by data in DB, or by any other source. So I have a notion of Module, which is just this: a separate way to validate addresses. I have an interface:
interface Module {
public void init(InitParams params);
public ValidationResponse validate(Address address);
}
There is some sort of factory, that based on a request or session state chooses a proper module:
class ModuleFactory {
Module selectModule(HttpRequest request) {
Module module = chooseModule(request);// analyze request and choose a module
module.init(createInitParams(request)); // init module
return module;
}
}
And then, I have written a Module that uses some external webservice for validation, and implemented it like that:
WebServiceModule {
private WebServiceFacade webservice;
public void init(InitParams params) {
webservice = new WebServiceFacade(createParamsForFacade(params));
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
So basically I have this WebServiceFacade which is a wrapper over external web service, and my module calls this facade, processes its response and returns some framework-standard response.
I want to test if WebServiceModule processes reponses from external web service correctly. Obviously, I can't call real web service in unit tests, so I'm mocking it. But then again, in order for the module to use my mocked web service, the field webservice must be accessible from the outside. It breaks my design and I wonder if there is anything I could do about it. Obviously, the facade cannot be passed in init parameters, because ModuleFactory does not and should not know that it is needed.
I have read that dependency injection might be the answer to such problems, but I can't see how? I have not used any DI frameworks before, like Guice, so I don't know if it could be easily used in this situation. But maybe it could?
Or maybe I should just change my design?
Or screw it and make this unfortunate field package private (but leaving a sad comment like // default visibility to allow testing (oh well...) doesn't feel right)?
Bah! While I was writing this, it occurred to me, that I could create a WebServiceProcessor which takes a WebServiceFacade as a constructor argument and then test just the WebServiceProcessor. This would be one of the solutions to my problem. What do you think about it? I have one problem with that, because then my WebServiceModule would be sort of useless, just delegating all its work to another components, I would say: one layer of abstraction too far.
Yes, your design is wrong. You should do dependency injection instead of new ... inside your class (which is also called "hardcoded dependency"). Inability to easily write a test is a perfect indicator of a wrong design (read about "Listen to your tests" paradigm in Growing Object-Oriented Software Guided by Tests).
BTW, using reflection or dependency breaking framework like PowerMock is a very bad practice in this case and should be your last resort.
I agree with what yegor256 said and would like to suggest that the reason why you ended up in this situation is that you have assigned multiple responsibilities to your modules: creation and validation. This goes against the Single responsibility principle and effectively limits your ability to test creation separately from validation.
Consider constraining the responsibility of your "modules" to creation alone. When they only have this responsibility, the naming can be improved as well:
interface ValidatorFactory {
public Validator createValidator(InitParams params);
}
The validation interface becomes separate:
interface Validator {
public ValidationResponse validate(Address address);
}
You can then start by implementing the factory:
class WebServiceValidatorFactory implements ValidatorFactory {
public Validator createValidator(InitParams params) {
return new WebServiceValidator(new ProdWebServiceFacade(createParamsForFacade(params)));
}
}
This factory code becomes hard to unit-test, since it is explicitly referencing prod code, so keep this impl very concise. Put any logic (like createParamsForFacade) on the side, so that you can test it separately.
The web service validator itself only gets the responsibility of validation, and takes in the façade as a dependency, following the Inversion of Control (IoC) principle:
class WebServiceValidator implements Validator {
private final WebServiceFacade facade;
public WebServiceValidator(WebServiceFacade facade) {
this.facade = facade;
}
public ValidationResponse validate(Address address) {
WebService wsResponse = webservice.validate(address);
ValidationResponse reponse = proccessWsResponse(wsResponse);
return response;
}
}
Since WebServiceValidator is not controlling the creation of its dependencies anymore, testing becomes a breeze:
#Test
public void aTest() {
WebServiceValidator validator = new WebServiceValidator(new MockWebServiceFacade());
...
}
This way you have effectively inverted the control of the creation of the dependencies: Inversion of Control (IoC)!
Oh, and by the way, write your tests first. This way you will naturally gravitate towards a testable solution, which is usually also the best design. I think that this is due to the fact that testing requires modularity, and modularity is coincidentally the hallmark of good design.

How to set custom JAXBContext

i would like to ask a question about #UsesJAXBContext annotation in jax-ws. I try to make it work on client side but I'm probably missing something. Here is my case:
I've got webservice with operation:
#WebMethod(operationName = "putToQueue")
public boolean put(#WebParam(name = "queueName") String queueName, #WebParam(name = "element") Object element) {
return queues.get(queueName).offer(element);
}
On the client side i generated QueueService and Queue (port)... and other stuff... [respones requests. In this case irrelevant.]
I would like to let user define object that he/she could put to queue. However to invoke operation put(...) I need bind object (that I try to send) into JAXBContext. I could do that by
#XmlSeeAlso in the top of the generated Queue stub [i tried this one and it works]. Nonetheless I need more generic solution that help me bind object at runtime.
I thought that I could create #QueueMessage annotation and ClientJAXBContextFactory and add marked class to the context when creating it.
public class ClientJAXBContextFactory implements JAXBContextFactory {
#Override
public JAXBRIContext createJAXBContext(SEIModel seim, List<Class> classes, List<TypeReference> references) throws JAXBException {
Reflections reflections = new Reflections("");
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(QueueMessage.class);
classes.addAll(annotated);
return JAXBContextFactory.DEFAULT.createJAXBContext(seim, classes, references);
}
}
Next i tried use #UsesJAXBContext on top of generated Queue.
#WebService(name = "Queue")
#UsesJAXBContext(ClientJAXBContextFactory.class)
public interface Queue {
...
}
But createJAXBContext(...) is not invoked and jax-ws just simply create his JAXBContextImpl.
I have read:
http://weblogs.java.net/blog/jitu/archive/2008/08/control_of_jaxb.html
http://www.techques.com/question/1-5627173/Specify-JAXB-Packages-in-SLSB-and-JAX-WS
and some question on stackOverFlow. I would be grateful for advises.
Is it possible to implement idea presented in my question?
Also i might add that on the server side ... #UsesJAXBContext works. But its important for me to make it work on the client side.
Ok I could manage problem i was facing. Still i couldn't use #UsesJAXBContext with client consuming the webservice. But i found that this annotations are tied to beans with post-fix Feature. So there is a class UsesJAXBContextFeature
https://jax-ws.java.net/nonav/2.2.7/javadocs/com/sun/xml/ws/developer/UsesJAXBContextFeature.html
and it could be passed as argument of port or service(service since jax-ws 2.2). I have got a little trouble with versions so i decided to generate class and use jax-ws 2.1. Now i just simply create port like this:
new QueueService().getQueuePort(new UsesJAXBContextFeature(new ClientJAXBContextFactory()));
And it works!

Communication between Java programs with non-JDK objects

I'm looking for a communication channel between two java programs running on the same machine. I've found a few options (RMI and XML-RCP) but none of the examples that I found show exchange of objects wich class it's non-primitive and not know on JDK (our own objects).
So, what's the easy technology to use when I want to do this (note that Utils.jar it's on the classpath of Server.jar and Client.jar):
Utils.jar:
class MyClassRequestParams { ... }
class MyClassReturnParams { ... }
Client.jar:
// Server creation
...
// Send request
MyClassRequestParams params = new MyClass...
MyClassReturnParams response = server.send("serverMethodName", params);
Server.jar:
MyClassRequestParams serverMethodName(MyClassRequestParams params)
{
MyClassReturnParams response = new MyC...
// do processing
return response;
}
Just make your transport classes implement the Serializable interface, and everything will be fine with RMI. Note that every object referenced bt the transport object should also be Serializable.
The RMI tutorial uses an example with a custom Task interface implemented by a Pi custom class that is not a "standard" JDK class.
You may also consider Versile Java (I am one of its developers). Follow the link for an example of making remote calls and defining remote interfaces. It implements a platform-independent standard for remote ORB interaction, currently also available for python.

Categories

Resources