I would like to develop a "database based" java desktop application in the following way:
Develop the Data Access Layer (DAL) using JPA (POJOs generated by Netbeans 7.4)
Develop the Business Layer (BL) (my own classes, controllers, etc.)
Develop the Presentation Layer (PL): Graphical User Interfaces (Panels, Frames, Dialogs)
Making the (PL) communicate with the (BL)
I developed the (DAL + BL) in a single Netbeans project (ProjectDBL.jar).
I developed the PL in a separate Netbeans project (ProjectGUI)
I am importing ProjectDBL.jar into ProjectGUI as a compiled library.
I didn't add the EclipseLink libraries to ProjectGUI since they were added in the ProjectDBL.jar.
I didn't add the database driver library to ProjectGUI for the same reasons.
I would like to fully separate between my DAL+BL and my PL. Further database modification (MySQL->SQLServer for example) should not impact all what was done in the PL.
The problem i am facing is a kind of exception raising when i want to invoke any method in the ProjectDBL.jar:
Exception in thread "main" java.lang.NoClassDefFoundError: javax/persistence/EntityNotFoundException
It seems as if the Persistence Unit must not be instantiated by an external jar...
A compiled library doesn't include all the libraries it uses. Otherwize, every jar file would be 50MBs large, and you would end up with commonly used libraries being present several times in your classpath.
You neet to add every library you use, directly or indirectly, to the classpath.
Consider using an Enterprise Application archetype for this.
Your DAL and BL would be contained in the EJB project, and the PL would be in the web project.
This specific case is exactly what this archetype is for, and will ensure that you're including the necessary libraries in each module, not just the compiled classes stripped of their dependancies.
As an aside, when using JPA, if your DAL/BL is encapsulated in EJB classes, you also get Container Managed Transactions, so it's a good idea to segregate classes as you have anyway, because you can take better advantage of JEE's extensive built-in plumbing.
Related
I want to make a java application that supports plug ins. Now my core will use jars for certain processes. If my plug ins where to also use these jars, do the plug ins of my application need to configure their build path to include the jars they would also use or is their a way so that the jars can be imported similar to how I import packages from the main application
Guice and Spring are tools for dependency injection, which means that creating objects is easier with them because they take care of instantiating objects and placing them into other objects that depends on them.
Now, when we talk about plugins, we usually are talking too about dynamically loading new classes into a running app. Think on eclipse IDE. Its architecture was designed from the beginning to be "pluggable", like, you can download jars and eclipse will add them to the running application without the need of application restart.
In this case, if you want to build pluggable apps, in a sense of dynamic classloading, I'd recommend you not to go through this path, but to research subjects such as OSGI. One popular OSGI framework is http://felix.apache.org/
Another approach for application extension (we may call this pluggable too, somehow, I guess), depending on how your app is organized and what it does, is to develop a DSL (http://en.wikipedia.org/wiki/Domain-specific_language) for it and extend it letting people adding scripts to it. Isn't something like this when a browser let you add pieces of funcionality written in javascript? Groovy makes DSL easier in some aspects, for java programmers. (see http://docs.codehaus.org/display/GROOVY/Writing+Domain-Specific+Languages)
If you want dynamic plugable systems OSGI can give you this, but OSGI its IMMO a over-complicated technology, use only if you are really sure that needs this dynamic plug-ability.
Other option for builds extensible systems its use de ServiceProvider mechanism, this is a core java mechanism, for example its the one that JDBC implementations use, you can put a JDBC driver in your classpath and the application can find it and use it without needing that you explicitly import the driver classes in your code.
This is an example of using ServiceProvider in your owns applications: http://docs.oracle.com/javase/tutorial/ext/basics/spi.html#limitations-of-the-service-loader-api
Its of course more limited than OSGI, but its very easy to use when you get the idea, and you don't need any external library because its a java core mechanism.
EDIT: about the libraries.
In runtime: With ServiceProvicer there is no separate classloaders (you can implement off course, but by default, in OSGI its implemented this separation), in runtime if your plugin need X class and this class is in the classpath all is ok, the limitation its that the main application and all the plugins use this version of the dependency (guice 3 for example) and you cannot have one plugin using X version and other plugin using X+2 version if this version are not compatible. (this is the famous hell .jar, and one of the principal motivations behind jigsaw project for example).
In compile time, include the dependency in your pom, ant build file, gradle build file or whatever build system your use as usual.
I´m working in the design of a java web application capable of executing custom code or precompiled classes uploaded by the users, focused mostly in simple validations of datasets.
The custom class must be constrained to a predefined interface and only some libraries and classes must be available to the custom class.
My first solution is to use a custom Classloader capable of loading .jar files from a defined directory in the file system. This approach seems to work but i´m concerned about the security and compatibility of this solution.
Is possible to limit the classes that can be imported by the custom class and run the code in a sandbox in order to avoid some actions like opening files or sockets?
When the loaded class will be unloaded?
application Servers like Weblogic have some restriction about using custom classloaders?
I have evaluated another solutions like OSGi Bundles, but it looks really complex and the support is limited in some applications server also i´m not really sure if OSGi is the right technology for this particular usage. Embedded Scripting Languages like Groovy o Javascript are discarded because the project owner wants the custom code precompiled and written in Java.
What would you recommend for this problem?
OSGi is a good fit for an application that wishes to accept external code (plugins). All the requirements you mention (predefined interfaces, loading jars, mutiple classloaders) are all covered by OSGi services and bundle management. Bundles can be installed, started, stopped, uninstalled, etc, including in runtime.
OSGi support in web application servers is not really that limited. You could even considered embedding an OSGi framework.
Security-wise you will need a solution around security managers.
I have a large scale project I am working on at the moment using Eclipse. Normally, as a one man team, these problems would not be an issue, but as our team is not one person we need to be able to break up pieces of the project to be worked on by certain team members.
In simplicity, let's say I have two layers to be separated apart:
1. Each DAO is a separate Java project, to be worked upon individually
2. The web-tier service layer contains all of our service endpoints and must be able to reference all of the DAOs. This layer runs on Tomcat as a dynamic web project, and utilizes Adobe LiveCycle Data Services as the piece that handles creation and management of endpoints.
Now, the issue we are running into is that when we create a DAO and unit test it individually it runs great. But when we reference it into our service project and try to run it we begin to get all kinds of issues related to the fact that we have two different versions of certain jars referenced in and as such we begin to have errors when running the server.
As a result, we know we can solve the issue by pulling the problem jars and ensuring that this is not an issue again in the future, but as I said before this is a large scale project with multiple people working on it and we don't want to be spending our time weeding out dependency issues when under the gun.
We are looking for recommendations on where to proceed for alternative solutions? Our team is new to JavaEE and as such we don't have much of a bearing on what we can use to tie everything together in it, or if it is a viable solution. Should we be looking at turning our DAOs into EJBs and deploying them in an EAR library? If so, where would our service layer lie, and would the service layer be able to reference the DAO classes since the EJB maintains it's own classpath (from what we have read?) Are we looking down the wrong path, or are we completely wrong in our current understanding of JavaEE?
Any assistance is greatly appreciated. We are still in the framework stage of this project and we want to be sure that we will be able to maintain it in the long run.
I second the Maven recommendation. That can add all sorts of sanity to your project structure.
Maven can even generate Eclipse workspaces via mvn eclipse:eclipse
An important clarification on the EJBs note. As of ava EE 6 is you no longer need to separate EJBs from Servlets and can use them together in the very same jar in the war file.
So understand from that that using EJBs or not no longer has any impact on packaging or classloaders as it once did. These are now separate decisions. EARs and classloader separation should now be viewed as a feature you might want to use should you want classloader separation and the complexity it brings. Most applications simply do not need that and are more than fine with just a war file containing servlets, ejbs, jpa entities, cdi beans, jaxrs services and whatever else you need. You are free to decide how you want to separate them or if you want to bother separating them at all.
EJBs do make great DAOs due to transaction management, something you don't get from plain Tomcat but can be made available in Tomcat via TomEE and works fine in Eclipse. You should consider EJBs for that reason, not for dependency reasons.
Side note, as you're new to Java EE, you might find this helpful:
http://openejb.apache.org/examples-trunk/index.html
In order to have things organized when working with Java EE in teams of 1+ people I could suggest:
Use Maven to manage your build process and library dependencies.
Maven has a small learning curve, but once you grasp it you will be grateful. By using Maven you no longer depends on Eclipse to manage your classpath.
A thing about it that I think is really helpful when working in teams is the install feature. Suppose you are woking on the version 1.0 of an EJB module, say core-ejb-module-1.0, and you've got it to a stable state and want everyone working in the project to refer to it from now on.
You then run a maven command like this on it: mvn clean package install
Maven will clean this module, compile it, run tests, create the jar and then install it to a repository that you define. Could be any computer in your company.
Now you may tell the guys working on other projects to update this dependency version on their .pom file and in the next build they run, before compiling, maven will download this library and then use it. Really neat. No more classpath hell.
(There are other ways to always automatically refer to the latest library as stated in this post, but there are some caveats. Anyway it's just an example.)
Use JPA/EJB instead of DAO Pattern.
Some people say DAO meaning any sort of data access, others really mean that they use the DAO Pattern to access objects. If that is your case, you no longer need to use it when using JPA. (At least for most common scenarios).
In my case, I have a generic EntityService which is capable of doing CRUD operations on any Entity and has a centralized query management. Then every EJB's that should perform database related operations may inject this guy and do its job.
As a suggestion, with Maven, you project could be organized as such:
core project structure
core (The pom root)
core-ejb-module (Includes all generic EJB's, like the EntityService for instance.)
core-jpa-module (Includes all JPA generic definitions, like Interfaces, MappedSuperclasses and such.)
core-jsf-module (Includes all JSF generic definitions, like abstract controllers, generic converters and wrappers for FacesContext, etc..)
Now that you have a core generic module setup, you could create:
an application structure
app (The pom root)
app-ear-module (Includes all other modules in this application. Shared jars goes in the ear /lib folder, so all other modules could reference to them.)
app-ejb-module-a (Includes EJB's for the business layer of your application. It uses the core-ejb-module)
app-ejb-module-b (You may have lots of ejb modules. You may even have a project that contains only ejb modules. Other apps will declare their dependency on them via Maven.)
app-jpa-module (Contains definitions for JPA Entities that represents you database tables. Depends on the core-jpa-module)
app-web-module (Holds the pages, Controllers and Converters for this application.)
I think you got the idea. Things tend to be loosely coupled and you may organize your projects as you like.
This is just a simple example to illustrate. I didn't explained a lot about Maven but if you're interested I think it will help you indeed.
I hope it gives you some ideas and may help you in any way.
[]'s
If you can run all the sub-components using the same set of dependencies, you may find it helpful to migrate to a Maven build.
With Maven, you can define a top-level project that manages all the 3rd party dependency versions in one place, so all modules are built, tested and deployed against the same library versions. You are also likely to find Maven a good fit for the multi-module approach you have adopted, as it ensures that a project is rebuilt correctly if one of its dependencies changes.
You would still be able to use dynamic web projects as before; Eclipse will automatically deploy the DAOs as part of the service project (IIRC you need to characterise the DAOs as utility modules).
If you do go down the EJB root, you are correct that each EAR will get its own class-loader, and can therefore use a varying set of dependencies. However, in your position I would tend to look at improving your dependency management first - it'll probably be cheaper and easier.
We want to integrate DROOLS with my current web Application which is based on struts 2. Is there a sample Application which could be used as reference?
Generally we are seeing all application use Spring+ Drools.
Also later on can it be possible to integrate Guvnor for a GUI of the rules created?
Yes it is possible. Drools is not tier specific, you can plug it into you Java application however you see fit. As a general rule you would incorporate it into your service tier, where all the heavy lifting is done.
Drools needs very little configuration (in many scenarios it needs none at all). Simply drop the applicable JAR files into your library folder and reference them in your classpath.
I actually built a prototype application for a client using Yahoo UI, Struts and Drools. It works like a charm (can't share the source unfortunately). To wit, you are definitely not tied to Spring.
As far as your second question, note that using Guvnor to manage rules and accessing those rules from your app logic are two totally separate things. The Guvnor governance application is bundled as a web app that you deploy on a server. Once deployed it provides a very nice interface that you can use for managing a rules repository. To use those managed rules in your application you need to include the appropriate JAR files in your application and do some configuration.
I would recommend standing up a simple application first that simple executes some rules in an embedded DRL, before attempting anything more complex like integrating with Guvnor.
My domain classes and persistance logic (Hibernate) are in one project called model. This jar is included within all of my apps.
Packaged com.company.model & com.company.persistance
Another Utils.jar - contains DateTime, String, Thread, etc general helper classes. This again is included within all of my apps.
Packaged com.company.utils
I have a CXF/Spring app that exposes services for manipulating my data. CRUD functionality, ALL other common functions. This is the 'way in' to my database for any app designed.
Packaged com.company.services and running on Glassfish app server
I have other apps that use the web services (Spring injected) to manipulate my data. Including a web app that will use YUI widgets and the XML/JSON from the web services for a nice smooth UI.
I understand its not really a question! I suppose Im looking for confirmation that this is how others are designing their software. If my architecture makes good, logical sense! Obviously there are security concerns - I will want some applications allowed to only access service x. I will address these later.
Sounds good.
It depends also of the type of application you're developing and the specific requirements for that ( it has to be deployed every week, it has to be deployed in several locations etc )
But so far sounds good enough.
Looks like you can formulate a question from here in the future for some specific scenario.
Since this is not a question, mine is not really an answer. CW
My only comment would be to put the persistence and Hibernate classes into a separate module; so that the model module can be purely beans/POJO/your domain classes.
Here's how I've organized a few multi-module projects before
project-data - contains domain classes and DAOs (interfaces only)
project-services - "Business logic" layer services, makes use of DAO interfaces.
Depends on project-data.
project-hibernate - Hibernate implementation of DAO interfaces.
Depends on project-data.
Conceivably if I were to use some other sort of data-access method I would just create a separate module for that. Client apps could then choose which modules to be dependent on.
Only suggestion I might have is that when you're creating service/models that you group them by subpackage name. ie
com.company.model.core
com.company.service.core
com.company.model.billing
com.company.service.billing
Also, be careful to ensure that no controller code (manipulating your UI) ends up in the services.