I am doing a webservice call and it responds with model class called Foo. Foo is not extending any other class.
Foo data = call();
I can access all data fields normally. String str = data.getData();
However if I do System.out.println(data.toString());
I am getting back the following output: com.package.Foo.$$$.Bar#2938ac9a
I suspect that web framework is doing some reflection magic around responses and wrapping it with proxy class. Since Bar is extending Foo on application level I can't notice anything and still can access all data I need. But...
Problem:
When I am trying to serialise Foo data; as a result I am getting a lot of unexpected data and fields.
I wonder if someone can explain me what does $$$ mean in java and how do I convert Bar object back to Foo?
This is typically a wrapper that some library uses to hide their implementation, with auto-generated code. Another instance (slightly different) can be caught while using Hibernate, which relies on the Proxy class from the com.sun.proxy package:
...
at com.sun.proxy.$Proxy38.getSingleResult(Unknown Source) // Who would name its class 'Proxy38' ?
...
See this other SO answer for more details.
You would have to write your own wrapper in order to succeed:
public Foo barToFoo(Bar data) {
Foo foo = new Foo();
foo.name = data.getName();
...
...
return foo;
}
This is one of your safest options. You keep control on the data, you can still access it, you are converting it back to Foo the way you want (and not some tricky conversion or hidden implementation), and you can handle any case you like (null data, exceptions, etc).
EDIT
It should happen automatically. Is there any solution [...] ?
It looks like there are not, unfortunately. There is an overloading solution in C++, but not in Java.
Related
I have thumbnails saved in my database as a byte array. I can't seem to workout how to return these to the frontend clients via GraphQL.
In a standard REST approach I just send a POJO back with the bytes and I can easily render that out.
However trying to return a byte[] is throwing
Unable to match type definition (ListType{type=NonNullType{type=TypeName{name='Byte'}}}) with java type (class java.lang.Byte): Java class is not a List or generic type information was lost: class java.lang.Byte
The error is descriptive and tells me what's wrong, but I don't know how to solve that.
My thumbnail.graphqls looks like:
type Thumbnail {
id: ID!
resource: [Byte!]
}
And the thumbnail POJO
public class Thumbnail extends BaseEntity {
byte[] resource;
}
I'm using graphql-spring-boot-starter on the Java side to handle things, and I think it supports Byte out the box, so where have I gone wrong?
Very fresh to GraphQL so this could just be an obvious mistake.
Cheers,
You have to serialize it to one of the standard types.
If you want your byte array to look like a string such as "F3269AB2", or like an array of integers such as [1,2,3,4,5] its totally up to you.
You can achieve the serialization by writing a resolver for your entity, like that:
public class ThumbnailResolver extends GraphQLResolver<Thumbnail> {
public String resource(Thumbnail th) { ... }
//or List<Integer> resource(Thumbnail th) { ... }
//or whatever
}
The resolver have always priority over your entity. This means that if a resolver method with the correct name, parameters and return type is found in the resolver class, this will be called instead of the entity method. This way we can "override" entity methods, in order to return an other result, even a different type than the actual entity field. By using resolvers, we could also have access to application scoped services etc that an entity typically does not have.
After writing your resolver, don't forget to update your schema file to:
resource: String
#or resource:[Int]
#or whatever
Your schema should refere to the resolver type since this is what graphQL recieves. The actual entity type will become then irrelevant to graphQL.
As a plan B, you could implement a new Scalar. This would be like inventing a new basic type. This is also not that hard. You can see the already existing scalar types here and do something similar.
You can then name your new type ByteArray or something like that, declare it in your schema:
scalar ByteArray
and then use it.
I would go for the first solution though since it is easier and faster to implement.
I'm developing an application where I would like to create a compiled and defined custom text-protocol. I.e. I want to send textstrings that represent information / actions to take in a server-client based system.
Is there any reference / best practice way to do this object oriented (in java)?
Some examples of the actual text strings that might be sent, for convenience separated with spaces (will be split by something else in the real case):
command1 <timestamp> <id> <arg1> <arg2>
command2 <timestamp> <id> <arg1> <arg2> <arg3>
command3 subcommand1 <timestamp> <id>
command3 subcommand2 <timestamp> <id>
So some things are included in all messages, but in other ways the messages could be totally different, depending on future implementations and so on.
What I would like to achieve with this is that the received textstring should be parsed with this protocol so that the parties that use it only have to pass the received text string to the protocol and then be able to switch to different functionality depending on the message type. My first thought was if it was possible to implement a base class, let's say "Message", and then subclasses for more specific message types (example Register or UpdateSomething).
Pseudo code to explain roughly what I wanted to achieve:
object msg = new Message(rawText);
switch (msg.getType()) {
case Message.Register:
// Register logic, data needed would be available in the msg-object.
// Most likely a function, for instance: handleRegistration(msg.uid, msg.password)
break;
case Message.SomeData.Get:
// logic/function to return SomeData, args/data needed would be available in the msg-object.
break;
case Message.SomeData.Update:
// logic/function to update SomeData, args/data needed would be available in the msg-object.
break;
default:
// Some default logic.
break;
But I realized that even if I was able to parse the rawText and somehow transform it into different objects depending on its contents (How can I do this?), it wouldn't be possible to switch on object type in a nice way and I've seen that many argue that it isn't a good approach.
I can get all this to work in lots of ugly ways, that's no problem, I'm just very unsure about the correct approach to this. I'd really like to learn how to do this in a nice and usable way also considering scaling (the protocol will grow). I want the protocol to just be a package (jar) that each party (different clients and the server) can use after which no one needs to bother with what (text) is actually sent over the connection.
Any help and guidance is greatly appreciated, I'm open to take other completely different paths. Do note again however that I'm not asking for help to just "get it working". I'm asking about the best practice(s) to implement those things, or references where I and others reading this can learn how to do this.
Thanks!
EDIT:
I guess the main problem I have is the problem itself. The messages differ quite a bit from each other, meaning I will end up in quite a few classes if I want the data members to be unique. This in itself isn't really a problem, it's just the names have to be unique as well. I'd like to group them up in some hierarchy.
For example with the REGISTER type:
A REGISTER message is a type of MESSAGE. But there are also different kinds of register messages:
REGISTER REQUEST <id> <password>
REGISTER OK
REGISTER ERROR <reason>
I would like to group these up in the sense that they are all register messages, but they are also different types of register messages with different payloads (ie need a different set of members if translated to objects). So if I'd like an object to be able to extract this information from variables I'd need 3 classes for this (example RegisterRequestMessage, RegisterOKMessage, RegisterErrorMessage) and it just feels as if all those classes and names could get a bit too much.
I wish to achieve:
Readability and usability for the developer using the protocol, when
they make their switch case to see which message they received or
when they make a new message they should easily (in a IDE that
supports it) be able to list the message-types they can choose from.
Be able to extract information from a message that is unique for
different message-types depending on what is being sent. I'd like the
data available to such a message to be visible (again in a IDE that
supports it) when the object is being used.
I guess there won't be any real smooth way here, either I'll end up with lots of classes (the problem is really lots of long names for messagtypes/classes), or I'll end up having to make it more generic, filling up a json-object or similar with the data.
Lots of classes:
handleRegisterMessage(MyLongNameSpecifiedMessageClass msg) {
this.id = msg.id;
this.password = msg.password;
// etc etc
}
More generic json or such:
handleRegisterMessage(JSONObject msg) {
this.id = msg.get("id");
this.password = msg.get("password");
// etc etc
}
I'm not sure if there's much more to do, but if you guys with more experience see some more elegant or easier solution here that I don't I'm happy to try it out.
EDIT 2:
Decided to use a unique class for each message type, even though there will be quite a few messages and the names might get somewhat long / ugly It felt like the most encapsulated and easy-to-use way. It will be compiled into a jar file and used that way anyways. Thanks for all suggestions though since other people might decide to take other paths.
If I understand what you mean, basically, a message is something that must
be parsed from a string,
be used to do something.
So, you could have something like
abstract class Message {
public abstract void doSomething();
private String myType; // or enum, or whatever
public String getMyType() {
return myType;
}
public static Message parse(String s) {
// parse s
// if s contains command 'register', return a new RegisterMessage
// if s contains command 'someDataGet', return a new SomeDataGetMessage
return // a newly created message;
}
}
class MessageRegister extends Message {
#Override
public void doSomething() {
// do what a Register message does
}
public MessageRegister() {
myType = "REGISTER";
}
}
class MessageSomeDataGet extends Message {
#Override
public void doSomething() {
// do what a SomeDataGet message does
}
public MessageSomeDataGet() {
myType = "SOMEDATAGET";
}
}
Then, you create a new message with
Message m = Message.parse("some command");
You can switch on the message type like this:
switch (m.getMyType()) {
case "SOMEDATAGET":
// whatever
}
The way I usually do this is with an interface, lets call it ConsoleProgram that takes string arguments and a HashMap that couples a string to a Program. Basically doing something similar to your switch statement and then each Program can worry about its own format when its passed the rest of the string (excluding the first program selecting part of the string)
public interface ConsoleProgram {
public String getProgramName(); //what the command string starts with to call this program
public void runProgram(String[] arguments);
}
Then a single class can deal with recieving strings and passing them to ConsolePrograms without ever worrying about what the ConsoleProgram actually does
public class Console{
public static HashMap<String, ConsoleProgram> availablePrograms=new HashMap<>();
public void registerProgram(ConsoleProgram program){
availablePrograms.put(program.getProgramName().toLowerCase(), program);
}
public void recieveCommand(String command){
String[] parts = command.split(" ");
ConsoleProgram program=availablePrograms.get(parts[0].toLowerCase());
if (program!=null){
System.out.println(
program.runProgram(Arrays.copyOfRange(parts, 1, parts.length));
}else{
System.out.println("program unavailable");
System.out.println(
availablePrograms.get("availableprograms").runProgram(parts, this, null)
);
}
}
}
This is something I myself use to support administrative functions within a game I am developing and it scales very nicely. Furthermore if a ConsoleProgram needs access to unusual things you don't need to have Console know about them, the specific ConsoleProgram can take those objects in its constructor before being registered using registerProgram
Instead of writing your own serializers/parcers I recommend using one of well-known tools that are created exactly for that.
One of my favourites is protocol buffers from google and there are many others.
With protocol buffers you would need to define your custom message formats (look at their simple java tutorial for reference), and then generate java code for it.
You would do it on both server/client sides, or, I guess you could simply include generated files along with dependency jar in your library and share it between server/clients.
This will have number of benefits :
You won't need to write your serializer/parser (and more importantly spend time debugging it!)
It is flexible, you can change/extend your messages in future
You are not limited to Java implementations, same message format can be understood by other servers/clients written in C++/Python.
Important edit: I added a depth level to the situation to better reflect my problem.
I have a GXT Grid with a ListStore of a certain type Foo. Foo happens to have some important object properties, including one of type Bar. Type Bar consists of two object properties: fooFoo of type FooFoo and barBar of type Barbar. These two can be null and have a String property description.
I want to use the GXT grid's filtering to filter the Foo object records' by their Bar value's FooFoo or BarBar description.
I tried to add a ValueProvider<Foo, String> barDescription(); to FooProperties, resulting in:
StringFilter<Foo> barbarFilter = new StringFilter<Foo>(fooProps.barbarDescription());
In which Foo#getBarBarDescription() is implemented as follows:
public String getBarBarDescription() {
return this.getBar().getBarBar().getDescription();
}
Is there a simple/convenient way to implement this behaviour in GXT? I have not found it.
The implementation I describe above is the one I have tried, but the filters don't show up in the grid at all, no further error messages.
In response to Colin's answer to the previous version of my question, I have tried the following:
#Path("bar.barbar.description")
ValueProvider<Foo, String> barbarDescription();
Hoping for it to call Foo#getBar().getBarBar().getDescription(). I suspect the possibility for FooFoo and BarBar to be null may be causing issues.
If you want to have barDescription() invoke getBar().getDescription() on your Foo objects, then try this:
public interface FooProperties extends PropertyAccess<Foo> {
#Path("bar.description")
ValueProvider<Foo, String> barDescription();
//...
}
The #Path annotation works the same here as it does in the editor framework - you can use it to specify the path to the property you want access to. This allows you to skip creating a getBarDescription() method in your own Foo object.
Another option is to just build your own ValueProvider implementation. Using PropertyAccess is a way to ask the compiler to do the work for you, but nothing stops you from doing it yourself. In this case, it might look like this:
public class FooBarDescriptionValueProvider implements ValueProvider<Foo, String> {
public String getValue(Foo object) {
//TOOD consider a object.getBar() null check?
return object.getBar().getDescription();
}
public void setValue(Foo object, String value) {
object.getBar().setDescription(value);
}
public String getPath() {
return "bar.description";
}
}
Note that this is almost exactly what the PropertyAccess generated version will look like, but it allows you to customize the behavior however you want.
Looking through the Play documentation for Java I noticed the following block of code:
public static Result show(Long id) {
Client client = Client.findById(id);
return ok(views.html.Client.show(client));
}
Source: http://www.playframework.com/documentation/2.1.0/JavaRouting
I am having some trouble understanding the second line, my understanding of Java Object creation is a typical constructor looks like the following:
Person john = new Person();
What is the second line doing? Creating a Object called client from Class called Client, also what is Client? It doesn't appear to be a part of the Play Framework, certainly I cannot find anything in JavaDocs.
Thanks
Edit:
I found this to be a good point of reference for the answer (http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html)
Also I think the class Client comes from the following documentation (http://www.playframework.com/documentation/1.1.1/controllers) with Client being just a example model class, the new documentation probably needs updating to clear up this confusion.
Pretty clearly, the class Client has a static function of findById, which takes a Long and returns a Client. Static functions are functions that are defined without any access to object properties, and therefore can be accessed through the class name, rather than having to be accessed through an object. Most likely, the class has a static property containing a collection of all clients in the system by index, and findById grabs an existing Client from that list.
I really have no idea where the class Client is defined, however. I've also made a quick look around for it, and couldn't find it in the obvious places.
There must be a static method called show(Client) on the views.html.Client class that returns some object. That object is passed into an ok(whatever) method, and that ok method returns a Result object.
You're missing some basic knowledge/experience. The sample you gave has nothing to do with routes and in this snippet only first line is important, second is just some hypothetical usage. De facto it could be just...
public static Result show(Long id) {
return ok("You want to display details of client with ID: " + id);
}
Although #BenBarden explained what is that mean correctly , this static method isn't declared anywhere, it's (again) hyphotetical usage of some ORM. For an example the real usage with Ebean's model will be:
Client = Client.find.byId(id);
Of course you can also declare own method in your Client model and name it the same as in the sample, however it will be just only wrapper:
public static Finder<Long, Client> find
= new Finder<>(Long.class, Client.class);
public Client findById(Long id) {
return find.byId(id);
}
Conclusions
You need to examine some samples available with your Play sources to get familiar with some basic syntax, fortunately you'll find it easy.
DO NOT MIX documentation from Play 1.x with Play 2.x they are not compatible!
I have the following code:
public void doJob() {
MyObj s;
for ( Object o : MyObj.all().fetch()) {
s = (MyObj) o; // ClassCastException here
if (!s.fileExists()) {
//Do some stuff
}
}
}
which is throwing this exception:
play.exceptions.JavaExecutionException: models.MyObj cannot be cast to models.MyObj
at play.jobs.Job.call(Job.java:155)
at Invocation.Job(Play!)
Caused by: java.lang.ClassCastException: models.MyObj cannot be cast to models.MyObj
at jobs.OrphanSurveys.doJob(OrphanSurveys.java:18)
at play.jobs.Job.doJobWithResult(Job.java:50)
at play.jobs.Job.call(Job.java:146)
... 1 more
(This method runs inside a Play Job class, if that matters.)
The MyObj.all().fetch() is returning an Iterable of some kind containing all of the MyObj objects in the database. MyObj inherits this method from the Play! Framework's Model class, if that matters. That's why it's returning a list of Objects rather than MyObjs, and I can't change how it works.
So, is there some reason that I can't cast back to MyObj? I can see how there would be some weirdness casting back from an Object, but Java seems to know what the class of the object used to be.
Thanks!
It looks like you have ClassLoader issues. The objects being returned by your fetch() method were loaded in a different ClassLoader than the one being used in the current thread to try and cast.
Try this to confirm. Add the three lines of code to your exising code.
for ( Object o : MyObj.all().fetch()) {
// Check classloaders
System.out.println(o.getClass().getClassLoader());
System.out.println(MyObj.class.getClassLoader());
break;
//
s = (MyObj) o; // ClassCastException here
if (!s.fileExists()) {
//Do some stuff
}
}
I saw a recent post here on StackOverflow that indicated that if two otherwise identical instances of the same class are loaded by different classloaders, you cannot cast between them.
Post in question
Check whether you are not subject to the multiple classloader condition here too.
From your stack trace, apparently, there's some other kinds of entries in your collection.
Use o.getClass().getName() inside your loop to know what is .all().fetch() really returning.
Note: Maybe some model.Survey objects?