So after reading about DDD and all it benefits and glory it seems like Java EE does not make it easy for you to do so. What I thought was to make a structure like this:
Domain
Repository
Application
View
However in the comment of this answer DDD and application layer it seems like the Application layer which I thought was going to be the layer with all the services annotated with #Stateful, #WebService etc is not the place it really should be in. It seems like the domain models should have these annotations.
So now the question is: How do people structure their applications? Where do you put the different annotations and how do they use each other. Could somebody please help me understand how I can structure an java ee 6 web application? Please help and say not how I do it in a specific tool or anything like that but where the actual classes goes and what the different layers are intended to do.
I am frustrated on where to start and how to organize.
There are no specific rules on how you should structure your application. Best would be to use common sense as well as observe how others are doing it.
You can generate a simple maven project provided by weld team to see how a basic Java EE application can be structured:
mvn archetype:generate -DarchetypeArtifactId=jboss-javaee6-webapp -DarchetypeGroupId=org.jboss.weld.archetypes -DarchetypeVersion=1.0.1.CR1 -DarchetypeRepository=central
For sure you will find many other examples on github or java.net
Here's an example that might be helpful -> EAR Testing
It's called "EAR Testing", but can just as easily apply to building war files. For purposes of this answer I'll change the eartesting directory mentioned in the example to wartesting
EAR files and WAR files are nearly identical since at the Java EE spec level we decided to allow war files to contain EJBs, CDI beans, and more.
That example uses the Maven build system and has two modules, one for the "data obects" and one for "business logic". Seems to fit with how you think of thinks and might be a helpful starting point. It contains a tiny sample application with unit tests for the EJBs.
You might not have read yet, but often people refer to EJBs as hard to test. There're not anymore and that example shows the latest spec compliant solution, so you can kill a few birds with one stone starting from that setup.
What that doesn't include is a module to create the final WAR file that you would deploy in production. To create that you'd just add a third module
wartesting/business-model
wartesting/business-logic
wartesting/business-war (added)
In the busines-war you'd have a pom.xml like the following:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.superbiz</groupId>
<artifactId>myear</artifactId>
<version>1.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>business-war</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.superbiz</groupId>
<artifactId>business-model</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.superbiz</groupId>
<artifactId>business-logic</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>javaee-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Then create the following directories:
wartesting/business-war/src/main/java
wartesting/business-war/src/main/webapp
And we'll say for example you add the following files to each:
wartesting/business-war/src/main/java/org/superbiz/Foo.java
wartesting/business-war/src/main/webapp/WEB-INF/web.xml
wartesting/business-war/src/main/webapp/index.html
Once built, you should get a war file under wartesting/business-war/target/ containing:
WEB-INF/web.xml
WEB-INF/classes/org/superbiz/Foo.class
WEB-INF/lib/business-model-1.1-SNAPSHOT.jar
index.html
Related
It's kind of hard to explain my problem with words, so I took a pic, which shows exactly what my problem is:
As you can see, I have 3 relevant modules, a global, genui and web.
genui depends on global and web depends on genui.
Directly, web doesn't depend on global, but through genui it obviously does.
As you can see, if I take a look at the hibernate version of web->genui->global, it is 5.2.14, but if I look at it from genui->global, it's 5.3.0.
There is not, and there have never been any versions of either of these modules other than 1.0-SNAPSHOT.
I tried cleaning, deleting the files from .m2/repository, and even tried purging the local repo completely, nothing worked. I have no idea where maven gets the 5.2.14 number, I don't remember ever putting that in. The version is received from a property in parent module.
I figured out that the problem is caused by the pom.xml of web module, more specifically this part:
<dependencyManagement>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencyManagement>
You probably need to exclude that repeated dependency from one of the spring ones... verify all your dependencies and look which are the ones that include hibernate. Check that you also have different versions for servlet-api.
I'm trying to extend some features to the scim api that are not supported.
I've added the following maven dependencies from WSO2 Nexus repository:
<dependency>
<groupId>org.wso2.carbon.identity.inbound.provisioning.scim</groupId>
<artifactId>identity-inbound-provisioning-scim</artifactId>
<version>5.1.4-SNAPSHOT</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.wso2.carbon.identity.inbound.provisioning.scim</groupId>
<artifactId>org.wso2.carbon.identity.scim.provide</artifactId>
<version>5.1.4-SNAPSHOT</version>
<type>war</type>
<classifier>classes</classifier>
</dependency>
I've identified that I need to change the org.wso2.carbon.identity.scim.provider.resources.SCIMUserManager (and its UserStoreManager), and also add a new endpoint in the org.wso2.carbon.identity.scim.provider.resources.UserFeature.
However, these are located within org.wso2.carbon.identity.scim.provider but it seems that the war dependency hasn't any classes attached (and the maven 'classifier' tag is in vain), therefore I can't import or inherit those classes.
So, how can I extend the SCIM Api by using the org.wso2.carbon.identity.scim.provider library but managed by Maven?
I may not understand your question well. Anyway, You can change scim endpoint (wso2.war) file and put into repository/deployment/server/webapp directory. Also, you can find the class inside WEB-INF directory.
I'll present a simplified version of our problem, but know that we have way more than 2 projects, and so on.
So, at our job, we have 2 projects -
A
B
where B depends on A through ivy.
Recently we added configurations to the mix, mainly default and test.
The problem we ran into is that in A we have test utilities, which B needs in order to run it's own tests, so we need B to get these utilities from A.
We've thought of 2 ways to solve this:
make the test configuration public
create a new conf - test-utils - that will be public, and A will publish it's own tests under that configuration
The problem is that both solutions seem somewhat forced, and I wanted to get an idea how people do this world-wide.
Any ideas?
Note:
This answer assumes you're using a Maven repository manager. (Something
like Nexus or Artifactory).
I suggest that you upload an additional "test-utils" artifact when publishing Project A. This means the primary Maven artifact would be:
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>ProjectA</artifactId>
<version>1.0.1</version>
</dependency>
and the second artifact is:
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>ProjectA</artifactId>
<version>1.0.1</version>
<classifier>test-utils</classifier>
</dependency>
For more details on how ivy publishes and retrieves additional artifacts from a Maven repository I would suggest reading the following:
how to publish 3rdparty artifacts with ivy and nexus
ivy:install from maven with classifiers
I have a multi-module project built with maven. I need to run the project's integration tests daily. It is not possible to do this during the standard maven build cycle, because on runtime the integration tests defined within the modules have circular dependencies, which are illegal for me to declare on their poms.
Instead, I have created a separate project named Global that lists all modules jars and test-jars as its dependencies. Global has the same parent as all the modules. The idea is that using maven-ant-tasks I will be able to get a classpath of all modules jars and test-jars and go on from there. Global's pom.xml dependency section is as follows:
<dependency>
<groupId>mygroup</groupId>
<artifactId>A</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>A</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>B</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>mygroup</groupId>
<artifactId>B</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
...etc
The problem is that I cannot seem to get a classpath that contains all jars and test-jars declared on Global's pom.xml (and their runtime dependencies) using the ant tasks available. I have tried (among other things):
<dependencies pathId="cp1" type="jar" usescope="runtime">
<pom file="${basedir}/pom.xml">
<profile id="DEV" />
</pom>
</dependencies>
[1] This one fetches all runtime dependencies. Nothing wrong with that.
<dependencies pathId="cp2">
<dependency groupId="mygroup" artifactId="Global" version="myVersion" scope="test" type="test-jar"/>
</dependencies>
[2] This one fetches all runtime dependencies along with Global-myversion-tests.jar, but no other test-jar.
<dependencies pathId="cp3" type="test-jar" usescope="test">
<pom file="${basedir}/pom.xml">
<profile id="DEV" />
</pom>
</dependencies>
[3] This one fetches nothing.
Obviously, declaring something like [2] once for each module will do the trick, but I am looking to create a setup that will not need to edit a gazillion files each time a new module is added or removed. BTW I am using maven-ant-task-2.1.3.
Thanks for any input.
---Edits for #yannisf accepted answer---
You should not ever have cyclic dependencies
I assume you mean for maven builds. Having cyclic dependencies on runtime is pretty common, for example:
Module A declares interface: UploadToDocumentManagementSystem
Module B implements it in : UploadToCoolDms (that way in the future, when the DMS system changes to CoolerDms module B can be replaced by a new implementation with no side-effects to the rest of the app).
Module B depends on A compile time (and, by definition, runtime as well)
Module A depends on B on runtime
Maven does not allow to declare this. The reason, that I can sympathize with, is that maven needs to complete build cycles (including tests) of multi-module projects in a specific order. Thing is, it is not really necessary to declare it if you get rid of any runtime dependecy to B for the tests of A (which is good practice and should happen anyway).
You should do things the maven way instead of resorting to ant-tasks
Fair enough, I can see how maven-ant-tasks was not made for this use.
In your global pom you are declaring dual types for the same artifact (jar, test-jar)
Is that a problem in general? For example module A contains some samples for its tests that I would like to use in the tests of module B as well. Is it wrong (by maven best practices standards) to declare that B depends on A jar (compile scope) and on A test-jar (test scope)? Won't an integration tests project justify to depend on a module as well as the same module's samples and resources used for its unit tests?
tl;dr version: I will attempt to rearrange the tests declared on the modules and create separate module(s) for integration tests (assuming I can get 20 developers to play ball). Thanks for the answer and for making me admit defeat and stop trying to make maven work with the project instead of making the project work with maven :).
You are trying to break the maven conventions in many ways. 1. You should not ever have cyclic dependencies, 2. You should do things the maven way instead of resorting to ant-tasks 3. In your global pom you are declaring dual types for the same artifact (jar, test-jar).
Although at first this might not seem to answer your question, you should take a step back and rethink your layout. Integration tests need all the dependencies and are much more demanding than unit tests. So, instead of trying to fit them into the existing projects, create a separate maven project in the same group, that will only host integration tests (under src/java/test, main will be blank) and will have as dependencies all the other projects.
I have a GWT project and I want to use some other in house GWT libraries as dependencies.
We do not want to include sources in our final build. Most open source GWT libraries include sources in the JAR, but we want to keep sources separate, use them to compile, then throw them away.
Is there a way to do this with Maven?
Set the scope to provided
<dependency>
<groupId>com.you.gwt</groupId>
<artifactId>gwt-ui</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
Brad's answer will fix the problem in a very narrow scenario. Setting the scope to provided totally avoids the jar from being pushed into War's lib. This is not what you would need in use case of the "lib" on to server side code. This usually happens
1) Constants.
2) DTO's/Beans.
3) RPC service interfaces
4) Request Factory proxy declarations
You have to have a mix of approaches.
1) Brad's approach when the "lib" in purely client and has no chance of being used in server clode.
2) Modularize code to have Constants/DTO's/Proxy/RF related interfaces and any such code in a project that generates two artifact jars.
A) One with classes only - to be used to push stuff in to web-inf/lib i.e scope compile/runtime.
B) Another with sources/classess - to be used with gwt compilation i.e scope provided.
Generating two jars might seem redundant. This is the only sane option i have tried. Keen on check whether there is any other option that will be suggested.
There are two kind of library (package in jar file) in GWT:
Server side library like "gwt-servlet.jar" does not contain source code in jar file and you can add maven dependency like this in your pom:
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<version>${gwtVersion}</version>
<scope>runtime</scope>
</dependency>
Client side library like "gwt-user.jar" which contain source code in jar file, this kind of library does not require to package in your war file and you can add maven dependency like this in your pom:
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>${gwtVersion}</version>
<scope>provided</scope>
</dependency>
Have a nice time.