I have 2 maven applications that should communicate via server socket and socket. If possible, I want to send the data as a Java-object, but for that I need both of those projects to include the class of the object.
If possible, I don't want to make a third maven project with the class and add it to the server and client project as a dependency. Is there any other way to do that?
Thanks for your answers!
You could make your server project a sub-project of your client project, meaning that your server has access to all the classes the client needs, plus some extras.
Alternatively, you can create a JAR containing shared classes, and install this to your local (or remote if you have access) maven repository, using mvn install (docs here: https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html)
For the actual transfer of data, you could serialize your objects using the Serializable interface, however there are many issues with this approach:
Fragile to class changes - if you change your class, old objects will likely break unless you manually manage this
Java-only - you will not be able to, for example, write your client in C++ and your server in Java, if you ever decide to do something similar.
Framework incompatibility - many popular frameworks work primarily with other formats, and cannot guarantee compatibility.
Instead, you can use:
JSONs - Using Jackson Databind, or Google Gson libraries, they are flexible, powerful and standardised
XML - Similar to JSONs, with some subtle differences
Google Protobuf - Also has some limitations but very underrated for resource-constrained environments.
Custom String Format - implement your own toDataString() and fromDataString() methods. This is only really feasible for small classes, as there are many issues with Unicode, escape characters, encodings etc that most libraries hide from you. This is more risky than other methods.
In general, I would reccomend JSON unless you have a good reason to do otherwise. I personally use Jackson, here is a link to a tutorial: http://tutorials.jenkov.com/java-json/jackson-objectmapper.html
Related
I am developing an Android application with my friend. I am currently responsible for the backend while she is working on the Android part. The backend is developed in Java using Lambda functions running in AWS Amazon Cloud‎. The frontend and the backend are totally decoupled (Lambda functions are exposed via REST APIs) except for the POJOs used on both sides. POJOs are serialized by the application into JSON when calling an API and deserialized again into POJOs (very same ones) by the backend when handling API requests.
We want to keep POJOs on both sides exactly the same for obvious reasons but we are wondering what the proper way to do it is. We see the following two options:
1) Simply copy code on both sides. This has the disadvantage of changing common code independently which, sooner or later, will lead to a misallignment.
2) Move POJOs out to a separate library and include it as a dependency on both sides. This seems like a more proper way to solve this issue but how do we ensure that both me and my friend know that a POJO has been changed? Let's say I remove one field from a POJO and create a new version of the shared library. I push changes to our repository and then... tell my friend that I made some changes so she should pull them, build the new version and include it in her project?
Is there a different (better) way to address this issue? Currently the backend is built with Maven but I can switch to Gradle if this would help automate things and make our code consistent (Android Studio forces Gradle builds).
I found similar questions of other people but they were either a bit different or remained unanswered:
Sharing POJOs between Android project and java backend project
Sharing one java library between Android and Java backend (gradle)
Sharing code between Java backend and Android app
There are certainly lots of other ways of doing this and better or not; I will leave that to you to consider.
But before going to sharing the POJOs, I ask you to take a step backwards and take a look at your architecture. You have essentially got:
a Java Backend with REST APIs, supporting JSON payload
an Android Application, capable of making REST calls and deserialising the JSON payloads.
If you note, above, the tech stack does not involve POJO on any level.
You see what I mean? POJO is an implementation detail for you and it is not wise to share it among your components.
How about looking into the future where you add more components to your architecture, say:
iOS application
Kotlin support for Android application
Will your inclination to share POJO code still be intact? Perhaps not.
From what I see, you should design and develop for a REST backend and a REST capable client. Thats all. That should be the bottomline.
So with that, coming back to your requirements of sharing the updates between the backend and the client, you can share the JSON schema between the two, instead of sharing the POJOs. And thereafter, employ an automated system (say, a simple script) to generate POJOs in the backend and the client.
This approach can have certain benefits. For instance:
You will be able to share updates now and in the future, as per your requirements.
This makes your modularity (or decoupling) better too because the backend and the client is not bound by the requirements to use POJOs. For instance, you can use Data class if you decide to use Kotlin in your client.
You can use versioned schema for future, for the times where the client cannot keep up with the backend, or the backend needs to update independently.
and more
Adding to the answer above, I would take advantage of the fact that both languages use Java compilers and apis. Whether the front end uses Java or Kotlin, you can call any of these api libraries directly from your code.
One api in particular, Json-B, provides methods for transforming your Java (or Kotlin) objects into Json for transport, then transforming the Json response back into Java/ Kotlin on the other end.
One caveat: I recently heard that at least parts of the javax.* package were scheduled for deprecation. They should work on Java 14 or lower, but if you are planning on updating in the future, this is something that you will want to consider.
For Java versions 9 or newer, you should also read this first. It will save you some time.
EDIT: Json-B is, in fact, disabled by default in newer Java versions (the package is included but 'hidden'), but the last article linked in the paragraph above talks about acceptable workarounds. IMO it is still the preferred option for working with Json in Java.
For jstl tags, an API javax.servlet.jsp.jstl-api-1.2.1.jar & implementation javax.servlet.jsp.jstl-1.2.1.jar are provided.
For servlets, an API in servlet-api.jar & implementation jar from tomcat or GlassFish are provided.
For collections, API like java.util.List & corresponding implementations like java.util.ArrayList & java.util.LinkedList are provided.
IDE Netbeans is another example.
Implementation jar includes both the API(mostly interfaces) and its implementation, What are the advantages in providing a solution with an API JAR and their corresponding implementations(a separate JAR), for programmers/developers to use?
For developing enterprise applications using java, Is providing an API the standard approach for stable contract between developers?
I have advocated separating the API from its implementation in my Practical API Design book. At that time I valued the simple library as well as modular library approaches. We used them both successfully when designing NetBeans Platform APIs. I usually felt uneasy when it came to vendor library style - a common approach used in Java EE world.
Later I realized the optimal solution depends on the desired degree of proximity (see my detailed explanation). In short, it depends how closely the API author is related to the one who implements the API. Is it the same person? Is it a group that sit down and agreed on a specification? Are they different, but we expect way more users of the library than those who implement it? Or do we expect almost every user to implement (something in) the library? The answer to this question then leads to:
None to many
One to many
Few to many
Many to many
Proximity classification. Each of them can be handy in some situations. However, my all time favorite is many to many approach with full featured modular library design.
1) If you put the API in a different jar, then you can let it be used by clients that can't access the implementation. For example:
You can exclude the implementation from the compile-time classpath of clients, to ensure that clients of the API don't require any particular implementation.
You can exclude the implementation from the run-time classpath of API clients (either via ClassLoaders like servlets do or separate JVMs), so that clients can't depend on any particular implementation, and so that they can use libraries that would conflict with the ones that the implementation uses.
2) Not really individual developers, but it's common to use a strategy like that to avoid conflicts and unwanted dependencies between different development teams.
This is because only the API is standardised, and multiple implementations are possible, and the API is an incomplete specification. In the case of servlets, in addition to the servlets API, which your Web App uses, there is the web application server (Tomcat or Glassfish). The application server is a large program, with many other features and APIs. For a Web Application, your servlets are not "the program"; the application server is. It is not that your servlets delegate to the server, the server delegates to your code (in a WAR).
In programming using an implementation, you might need the API specification (interfaces, abstract classes etc) too.
Interface obj = new ClassImpletingInterface();
which could also be done as
ClassImpletingInterface obj = new ClassImpletingInterface();
If your program used only the latter, you might get away having just the implementation jar that didn't include the API package. As far as possible, one should use the former for better maintainability etc. Now the question of why can't the API package just be bundled into the implementation jar - one API one jar. Might sound simple, but may not be desirable. You might prefer to use the javax.servelet.jsp.jstl-api package obtained from the authentic source; not bundled in com.newbie.servlet-0.0.1.jar. There can be legal aspects that prevent such bundling. Further, an implementation not necessarily provide functionality for the complete specification. Your imports for an API could come from two different implementations as different parts, and they could be for different release levels of the specification. In that case, perhaps rare, each bundling a different release level of API may cause trouble because jar search within a directory is not completely defined. So, bundling of API and implementation into separate jars is cleaner.
I'm working on a server engine, and I am not sure in what form to distribute it. It is quite modular and it uses interfaces/abstract classes.
Should it be:
a library (no entry-point, write your own main() and call new Server().setSomeHandler(myHandler).run())
a binary (executable entrypoint with config file where you can inject JAR with handlers)
something else?
Basically, the developer should be able to completely extend or change the way the server works. I don't like the idea of making it a library because it should be a platform by itself, a whole server system.
Providing a programmatic way is more versatile than just an executable. And both ways aren't mutually exclusive. After all, even if a developer provides a handler, internally you probably still need to call something like the setter in your example to actually use that handler. Exposing that API shouldn't be too difficult. You could still provide a small launcher application that loads some config file and wraps it in some API calls, if that is needed.
The more important question would be, are there predefined extension points where developers can plug in their own implementations or is everything completely modular and exchangeable?
For a simple way to provide implementations of predefined interfaces, you can use the ServiceLoader/SPI mechanism. You can built a basic plug-in system with it.
If you want to create a platform, something like OSGi seems more appropriate. Here you could define APIs/SPIs for fine grained components/services. Developers could then provide their own modules that extend the server or even replace your default modules.
I need a framework to transfer POJOs between two (or more in a client/server model) Java programs over TCP/IP. I need it to be as simple as possible but it must support several clients per server, and easy implementation of encryption is a plus.
So far I have looked at Java RMI, JRemoting, AltRMI and NinjaRMI. Right now JRemoting looks like the best choice as it is simple and don't require strange and seemingly unnecessary extends and implements as most of the others do. No active development seems to be going on on any of them except a little on Java RMI. I don't know if that is because they are stable and don't need more development, or because these kinds of frameworks are just not "cool" any more.
The POJOs are just bags of properties. I need the server to hold a static list of objects, and the clients must be able to (1) Read the list, (2) Add an object to the list, and (3) Remove an object from the list.
Any suggestions?
You could probably use any serialization technology, for example you could use JSON and add on encryption and compression later in order to cutdown the amount of traffic you are sending. JSON has the advantage of being language agnostic, so you don't restrict the implementation of either side of the connection.
Many JSON libraries are available; see json.org.
Do you need to do remote method calls, or are your POJOs just bags of properties? If the latter, it would probably be easiest to just use plain Java serialization.
look here: http://code.google.com/p/google-gson/
You can have a look on Protocol Buffers. I think Google uses Protocol Buffers internally.
I'm looking for a super simple JSON or YAML library (not particularly bothered which one) written in Java, and can be used in both GWT on the client, and in its original Java form on the server.
What I'm trying to do is this: I have my models, which are shared between the client and the server, and these are the primary source of data interchange. I want to design the web service in between to be as simple as possible, and decided to take the RESTful approach.
My problem is that I know our application will grow substantially in the future, and writing all the getters, setters, serialization, factories, etc. by hand fills me with absolute dread. So in order to avoid it, I decided to implement annotations to keep track of attributes on the models.
The reason I can't just serialize everything directly, using GWT's own one, or one which works through reflection, is because we need a certain amount of logic going on in the serialization process. I.e. whether references to other models get serialized during the serialization of the original model, or whether an ID is just passed, and general simple things like that. I've then written an annotation processor to preprocess my shared models and generate an implementing class with all the getters, setters, serialization, lazy-loading, etc.
To make a long story short, I need some type of simple YAML or JSON library, which allows me to encode and decode manually, so I can generate this code through my annotation processor. I have had a look around the interwebs, but every single one I ran into supported some reflection which, while all fine and dandy, make it pretty much useless for GWT. And in the case of GWT's own JSON library, it uses JSNI for speed purposes, making it useless server side.
One solution I did think about involved writing writing two sets of serialization methods on the models, one for the client and one for the server, but I'd rather not do that.
Also, I'm pretty new to GWT, and even though I have done a lot of Java, it was back in the 1.2 days, so it's a bit rusty. So if you think I'm going about this problem completely the wrong way, I'm open to suggestions.
Have you looked into itemscript? Some excerpts from the description on the webpage:
A cross-platform GWT & standard Java JSON library, with convenient classes, parsers, and utilities.
A RESTful connector API for retrieval of data (JSON, text & small binary files) over a variety of protocols.
The same JSON API can be used in both standard Java and in GWT Java.