Cross-framework Solutions for field Annotations - java

Does anyone have any strategies or examples of cross-framework libraries?
I am working on a project with an android app, a java server and a Java desktop client, which all use different frameworks. I need to refactor some core business logic into a separate library that can be used across all of these to ensure consistent behavior, but the field annotations are killing me.
The problem is that I am using Room in the Android app (which requires the #PrimaryKey annotation on the primary key field of a database entity) and JPA in the server and JavaFX client (which requires #Id).
Given this level of difficulty with the models, we initially copy-pasted the fields without annotations to the others when changing them. However, the business logic needs to make use of the models and accommodate each platform's specific ORM, Http client and Json serializer. (I know that it is technically possible to get Gson, Apache Http and Hibernate to run on all of these platforms, but actually doing any of these solutions created too many nightmares of its own)
As far as I can tell, there isn't a nice solution to this. Fortunately, the same #Inject is used in Dagger2 and CDI/CDI-SE so I have created some interfaces that each platform/framework will implement.
Does anybody have any examples or case studies I could look at which might help me arrive at a solution?
(I realize this question doesn't include any code samples, but it's more of a general programming strategy question.)

Disclaimer: I am the architect of JDX for Java and JDXA for Android ORMs.
You may consider using JDX for Java and JDXA for Android ORM frameworks to share the common object model, the core business logic code, and the data integration code across Java server, Java desktop, and Android platforms.
JDX and JDXA don't use annotations to define the mapping - instead they use an external text file to define the mapping specification based on a simple ORM grammar. So you may use the same mapping specification for your common object model across different platforms. Also, the APIs for both JDX and JDXA are simliar.
So, you just need to use the appropriate JDX(A) ORM library for your target platform and an appropriate JDBC driver for your target database without needing to change your object model or business logic.

Related

Dynamically generating mappings between POJOs and REST API

I have a POJO class and I need to call a RESTful web service using some properties from the POJO as parameters to the service. The caveat is that I won't know the endpoint and its parameters 'till runtime. Basically, the user will configure at runtime the endpoint, input/output schemas and mappings from/to those schemas to the POJO class. Then I have to call the API with the appropriate values.
This is going to be a really broad answer.
It sounds like a question that would benefit as 'code as data'.
What I mean by this, is that the amount of possibilities that you have to be able to deal with at runtime, is close to the complexities of using a programming language itself.
When this happens, there's generally a few choices that people either choose by accident, or consciously choose depending on who the user is.
Limit the scope of the problem, and make your configuration that complex it may as well be a programming language itself.
Embed a scripting language, or create some runtime loading of plugins in the native language.
Use an off the shelf library / solution.
I'd recommend 2 or 3 over 1 if your user is yourself or the configuration can be provided by another programmer.

Is it possible to add new JPA/Spring entity in runtime to the running Java web application

I am trying to create web application that allow its users to create new forms and tables (many ERP applications have such feature). It is clear about generating and saving HTML forms and it is clear about generating new tables in database as well. But what about entities, e.g. Spring #Entity and #Repository classes.
One can try to compile then on the fly and save into the web application deployment directory, that should be possible. But is there need to update some kind of internal Spring registry of existing beans, repositories and controllers. Does Java JPA have such registry as well?
Is it possible to do such kind of thing? It is clear that it is possible to do this in php, e.g. to dynamically update yii framework application, because there is no compiled code (except, maybe, cached code) and with each new request the available paths are scanned anew. But how this happens in Enterprise Java and Spring applications?
Maybe I should look for Groovy Grails or Scala Play - they may be more dynamic languages.
More "object java storages" compatible with JPA (ObjectDB and Co) promise smoother, more natural migration with extra fields and classes. I haven't personal opinion.
EDIT: good perspective has, I think, philosophy ActiveRecord and similar. Few solutions in Java are ready. I have tried such solutions with partial success, but my project was not too dynamic (classes were stable) and we switched to clear JPA.
some ERP applications (in different languages f.e.C,Java.C#) have an idea "kernel class and additional fields", ie. Customer with all typical fields plus "Preffered color" (usually implemented in extra hidden tables). This is OK if they don't need new relations
Eclipselink has similar concept 'extra fields' in JPA area (not strict standard JPA but extension) https://wiki.eclipse.org/EclipseLink/Examples/JPA/Dynamic
At project level, seems to be OK enter non-critical data
3 Ist hard to imagine create high count of dynamic important/central classes (tables) without radically redesigned application (proverbially version 2.0 ;) )
Sometimes I try stop and restart EMFactory with different Persistence Units (in Tomcat environment) with Hibernate and Eslipselink, but not use in production. Reset & start seems be ok, this is like rupture and new life of JPA engine. Its more like application 2.0 than small patch.
Creating multiple gemmini table sets (for different companies in the same database) is good in Hibertate and Eslipselink (prefix before table name), few dedicated lines by start, normal clean JPA use. Tested, all OK.
Once again, adding single/few tables is poorly reworked in the community.
It is an interesting discussion to "glue" together common JPA modules (code+JPA), this is done often by OSGI programmers.
Theoretically so it has to module give your tables, strongly connected in the same PU.
At the ERP application level it can be anything from "add CRM module" to "kernel + sales".
I'm an interested spectator, but i have not seen any success.
If you look in the google integrate persistence unit from parts, composite persistence unit, many programers try to reach such target.
It is like a fishing rod rather than fish (as the old adage goes).
Persistence Unit conception isn't friendly for such ideas (and is blocked in standard JPA).

Hibernate objects and GWT-RPC

I want to transfer hibernate objects with GWT-RPC to the frontend. Of course i can not transfer the annotated class because the annotations can not be compiled to javascript. So i did the hibernate mapping purely in the ".hbm.xml". This worked fine for very simple objects. But as soon as i add more complex things like a oneToMany relationship realized with e.g. a set, the compiler complains about some serialization issues with the set (But the objects in the set are serializable as well).
I guess it does't work because hibernate creates some kind of special set that can not be interpreted by GWT?
Is there any way to get around this or do i need another approach to get my objects to the frontend?
Edit: It seems that my approach is not possible with RPC because hibernate changes the objects. (see answer from thanos). There is a newer approach from google to transfer objects to the the frontend: The request factory. It looks really good and i will try this now.
Edit2: Request factory works perfectly and is much more convenient than RPC!
This is a quote from GWT documentation. It says that hibernate changes the object from the original form in order to make it persistent.
What this means for GWT RPC is that by the time the object is ready to be transferred over the wire, it actually isn't the same object that the compiler thought was going to be transferred, so when trying to deserialize, the GWT RPC mechanism no longer knows what the type is and refuses to deserialize it.
Unfortunately the only way to implement the solution is by making DTOs and their appropriate converters.
Using Gilead is a cleaner approach (no need for all this DTO code), but DTOs are more ligtweight and thus produce less traffic through the wire.
Anyhow there is also Dozer, that will generate the DTOs for you so there will not be much need for yo to actually write the code.
Either way as mchq08 said the link he provided will solve many of questions.
I would also make another suggestion! Separate the projects. Create a new one as a model for your application and include the jar into the GWT. In this way your GWT project will be almost in its' entirety the GUI and the jar library can be re-used for other projects too.
When I created my RPC to Hibernate I used this example as a framework. I would recommend downloading their source code and reading the section called "Integration Strategies" since I felt the "Basic" section did not justify DTO. One thing this tutorial did not go over as well is the receiving and sending part from the web page(which converts to JS) so thats why I am recommending you downloading their source code and looking at how they send/receive each the DTOs.
Post the stack trace and some code that you believe will be useful to solving this error.
Google's GWT & Hibernate
Reading this (and the source code) can take some time but really helps understands their logic.
I used the next approatch: for each hibernate entity class I had client replica without any hibernate stuff. Also I had mechanism for copy data between client <-> server clases.
This was working, but I belive current GWT version should work with hibernate-annotated classes..
On a client project, I use Moo (which I wrote) to translate Hibernate-enhanced domain objects into DTOs relatively painlessly.

Is it possible to build a web application as a generic product rather than a one-time customized solution?

There is a business problem that needs to be solved. The obvious solution is an enterprise web application - a locally hosted website that provides the desired functionality.
I want to build this web application, but build it such that -
Its more of a product than a one-time solution; such that it can be customized for different clients
It is possible to provide 'fixes' for this web application, so that bugs can be removed and enhancements added with minimum impact on operations
The web app should be capable of working with different databases and existing authentication systems
Is this even possible? Is it a common enough approach that there is a known way of going about this? Would it be better to use an application framework like Spring or try and keep dependencies on frameworks to minimal?
Also, any links or references to books that will guide me will be greatly appreciated.
Thanks in advance StackOverflow!
(I feel like I dont know all what I need to know before embarking on this project, please feel free to point out things I haven't and should consider)
Developing software, esp. for re-usability, requires analyzing which parts/functions are common between use cases and which aren't, drawing the line between re-usable (library) and customized/specialized code.
If you know what use cases you expect or want to support in the future this can be feasible.
If you don't, you should not start trying to generalize arbitrary functionality in the first place, because you cannot know what you will be needing in the future.
Java provides some good abstractions of various functionalities, like universal DB support via JDBC.
If you didn't already, have a look at application servers like JBoss or Glassfish. They provide plenty of basic functionality for web applications, support very loose coupling between components, and are highly configurable. To switch from one DBMS to another, for instance, it is enough to alter a single line of configuration (given the supported SQL is similar enough). Deploying applications or parts can often be done on the fly ("hot deployment") without even stopping the server.
Plus: There is a vast amout of supporting libraries and frameworks out there to help you standardize your application design.
I have been working for a while on a webapp that can be deployed in multiple locations: it is designed to be instantiated on many hosts. It's entirely possible to do this, but it is difficult. Writing the code so that it can work this way takes a great deal of care.
The key to doing it is to make all your dependencies on things explicit and all your configuration driven by properties that can be set during installation. Spring makes this quite a lot easier! In particular, the org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer class allows you to use the servlet context as a source of values that you can then inject into your beans (e.g., via #Value annotations). It's far harder to do all that yourself. Here's (a simplified version of) what I use:
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="contextOverride" value="true" />
<property name="location" value="/WEB-INF/default.properties" />
</bean>
This merges the servlet context's properties on top of the ones you provide as defaults inside your webapp (definitely a good practice if most things aren't going to need to be modified most of the time) and then uses them to define properties. I then apply a configuration property (e.g., foo.bar) to a bean property using a placeholder, like this:
#Value("${foo.bar}")
public void setFoobar(String foobar) { ... }
Things to configure that way include the database configuration, absolute locations of files holding things that can't be packaged inside the webapp, etc. You'll have to use your skill and knowledge of the application domain to work out what things need to be listed.
Other key principles are to keep as much as possible inside the webapp (so reducing the opportunity for the deployer to mess it up), to be very careful about documenting everything, and to try it with multiple servlet containers. Remember, the person deploying your webapp does not have access to the contents of your thoughts: you have to write it down and tell them exactly what to do. (Too many instructions are at the level of “click this, click that, magic happens” but those are poor instructions since the exact method will vary over time: saying why will help far more because its more portable.)
We are currently developing a product that can be deployed internally for multiple clients and also as a public portal solution. Here is our experience.
As others have pointed out, there are different factors to keep in mind.
Security
Security that is associated with your product, and how you would manage the product functional requirements to external security roles.
Security, authentication and authorization should not be as part of the base product. Once authorized the roles need to be mapped to product roles for achieving said functionality.
Images and logos, that require customization.
Internationalization.
For working with multiple databases, assuming a product has typically two different views, persistence and querying. Our experience was to use hibernate to support multiple databases, but theoretically we have used only two databases in the past. db2 and mysql.
Testing for multiple databases for every release of your product is a pain. Your test cases goes 3 fold or atleast once in a while to support multiple databases.
Using custom databases and functions are a big no, you can use some general functions but custom database specific functions in your query are going to be a pain and have to be very diligent to avoid them.
Supported browsers in your product.
Licenses of the third party jars may not be compatible / acceptable to all institutions so you have to watch out for that carefully.
As much as possible, enable properties or configuration to customize all variables.
Caching strategy and properties initialization strategies.
A framework helps the team to keep on the same page, rather than an internal framework. There are many advantages to use a well established framework like Spring for performance and other consideration.
Cheers!

Transparently storing class state without exposing implementation

I have a model (MVC) class whose internal state (which basically contains of private int fields) I want to store.
The program is running on Android (for now) so I need to store the in a Bundle, but I'll be using the same class later in a desktop application where I'll have to store the state some other way, so I can't reference Bundle directly in my class.
So my question is: What is the best way to store (and retrieve) the state of a class without exposing it's implementation?
The best I could think of removing the private access modifier so that the fields become package accessible and create read/write helper classes in the same package, but that somehow seems wrong.
I'm not familiar with the persistence mechanisms on Android, but in general, it's a good idea to separate your persistence logic (i.e. the code that stores objects' state) from the domain objects that actually contain the data. That's the approach taken by JPA and virtually all modern object-relational mapping tools in Java, for example. So yes, referencing Bundle objects directly in your domain classes doesn't sound like the right strategy, especially if you plan to use the same classes in a non-Android environment, too.
My advice is to serialize the object state into XML, which is portable across environments. There are lots of open source tools available that help make this easy and don't require any special code in your domain classes. The two I'm most familiar with are JiBX and Castor. I don't know if either will work on Android, but even if Android has its own tools to transform objects to and from XML, you still might be able to use JiBX or Castor on the desktop side, since they can adapt to many different XML formats.
Once you have the data in XML form, you can persist it using whatever means is most appropriate on the target environment. On the desktop app, that probably means files in the user's home directory. On Android, I guess it would be bundles, but that's not my area of expertise. Good luck!
Take a look at the bridge pattern, as well: http://en.wikipedia.org/wiki/Bridge_pattern
As Rob said, you need to decouple the persistence from the data objects, so you can handle data uniformly and use a bridge to handle the persistence in different platforms.

Categories

Resources