I'm trying to build a Maven-Eclipse project, which can handle many implementation.
Its a MVC project. I want a common controller, and to have two (or more) service/dao implementations.
The controller project has lots of interfaces for the other ones (Services, Daos, Entities).
I want something like this:
Currently, I have something more like this.
It "works" and generates working wars when build:package, but i can't make it work on Eclipse. I'm getting the error below when I start the Tomcat 7 (using JDK 7).
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'entityManagerFactory' defined in file
[D:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp4\webapps\Impl1\WEB-INF\classes\spring-database.xml]:
Invocation of init method failed; nested exception is
java.lang.NoClassDefFoundError: ar/com/company/ml/core/entity/Publication
Publication is an interface in "Controller" project.
I'm using
org.eclipse.m2e.maven
Maven Integration for Eclipse JDT Annotation Processor Toolkit
Thank you and sorry for the images, I think they will be usefull.
Please help me organize this, or provide any good tutorial with this structure.
Controller POM:
<parent>
<groupId>ar.com.company</groupId>
<artifactId>Packer1</artifactId>
<version>3.0.0</version>
</parent>
<artifactId>ControllerProject</artifactId>
Packer1 POM:
<groupId>ar.com.company</groupId>
<artifactId>Packer1</artifactId>
<version>3.0.0</version>
<packaging>pom</packaging>
<modules>
<module>ControllerProject</module>
<module>ServiceImpl1</module>
</modules>
Related
In my pom i have ehcache 2 dependency
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${ehcache.version}</version>
</dependency>
The problem is that during application build we have a grype check for vulnerabilities and it detects couple of libraries inside this dependency:
NAME INSTALLED FIXED-IN VULNERABILITY SEVERITY
jackson-databind 2.11.1 2.12.6.1 GHSA-57j2-w4cx-62h2 High
jersey-common 2.31 2.34 GHSA-c43q-5hpj-4crv Medium
jetty-server 9.4.39.v20210325 9.4.41 GHSA-m6cp-vxjx-65j6 Low
It is a bit confusing because libraries added to ehcache jar in really strange way - not like dependencies but files with extension *.class_terracotta in folder "rest-management-private-classpath" which is shown on
screenshot
Because of this approach libraries versions can not be overridden or excluded in pom file.
Probably proper approach would be to migrate from ehcache 2 to 3, but it might take some time and i'm wondering if there are any fast solution to exclude this libraries from ehcache jar or override their version?
P.S.
When i check ehcache doc it says that dependency should be added with type pom
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.4</version>
<type>pom</type>
</dependency>
but if i change it to this type in my pom - cache manager in not initialized and i'm getting this error
Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'sessionRepositoryFilterRegistration' defined in class path resource [org/springframework/boot/autoconfigure/session/SessionRepositoryFilterConfiguration.class]: Unsatisfied dependency expressed through method 'sessionRepositoryFilterRegistration' parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.session.JdbcSessionConfiguration$SpringBootJdbcHttpSessionConfiguration': Unsatisfied dependency expressed through method 'setTransactionManager' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: 'entityManagerFactory' depends on missing bean 'cacheManager'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cacheManager' available
Sometimes library artifacts are released in multiple ways.
One way packages all needed dependencies so it can be used as-is without addition of extra dependencies. The challenge with that is just what you observed here - those embedded dependencies cannot be excluded or changed. org.hamcrest:hamcrest-all is an example.
Some libraries also have a "lighter" version - one containing just the classes etc. for that specific artifact. Then, we can explicitly add other dependencies to get the desired functionality - and we are fully in control of what versions etc. are used. org.hamcrest:hamcrest-core and org.hamcrest:hamcrest-library are partial replacements for hamcrest-all (more dependencies are likely needed to get the complete functionality provided by the -all version).
Personally I much prefer the second way because issues like the one encountered are tricky to find and debug.
So, the fix here is to see if there is a "light" version of Ehcache version 2 and switch to it (along with any other dependencies you need for core functionality) instead.
If there isn't one, and you absolutely cannot switch to version 3, then you could pursue using the maven-shade-plugin to rebuild the ehcache jar, filtering out the extra dependencies. I would highly suggest against this, as who wants to rebuild the ehcache jars with every version update? And it's possible if not likely that the (now mangled) library won't work properly anyway. Plus it would have to be manually uploaded to the team's artifact repository, ideally with a classifier or a different group ID to make it clear that this is not the official release. And if all of this is making your head spin, that's a great justification for doing the upgrade. :)
We are using a parent pom that has a child module where we have 2 pom files - the one named pom.xml and other being images-pom.xml.
This is the situation because we are doing some naming changes and for the time being we want to have them both.
In our parent pom we have the following code
<modules>
<module>child</module>
</modules>
<packaging>pom</packaging>
By default it seems that this is looking and trying to build the pom.xml - but in reality we want to use the images-pom.xml Is there any way to achieve this without creating a new module and using profiles?
I have a spring Boot application. I package it with maven, and I execute it with java -jar xxx.jar. The application is running. However if I copy the jar on another machine (same java version, same OS) I get a dependency error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name
'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration':...
...
Unsatisfied dependency expressed through constructor parameter 0
...
Bean instantiation via factory method failed
...
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [javax.sql.DataSource]:
Factory method 'dataSource' threw exception; nested exception is java.lang.NullPointerException
I added debug=true to show the classpath during execution, but it seems the same on both machines (there were issues with classpath order between maven execution and java execution)
EDIT: actually the problem is not changing machine: if I just move the jar in another folder, I get the same error. If I look at the correct running process it seems fairly obvious that in the classpath there are references to ther project target folder that cannot be satisfied...
Original machine is iOS, I tried the jar on other iOS and a Centos machine with same result.
I thought jar was very portable for deployment, so I don't understand if there is a better way of deploying the application or some environment variable I'm not taking into account
EDIT: I use maven. I do
mvn package
or
mvn clean install
and I have the dependencies mentioned in the answer
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
You need to create a Fat jar (a jar file with all the dependencies), you can find a more detailed info here, but to let some code in the answer:
Basically what you have to do is check that you have the right dependencies in your pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.1.RELEASE</version>
</plugin>
</plugins>
Then you should do
mvn clean install
And run it!
java -jar <artifact-name>
EDIT
What do you see if you do a repackage? mvn clean package spring-boot:repackage
Your HibernateJpaConfiguration bean cannot be created. It looks it has some property declared in a #Configuration annotated class or in the application.properties resource file. Some property that has a relative path in it, and when you move the jar it cannot find that property.
Actually it was a trivial issue: a directory had to be listed from a relative path and in order to execute the jar somewhere else I had to just create that directory.
The error wasn't properly catched so the stacktrace was showing failure in dependencies and I missed the simple reality: java.lang.NullPointerException....
Thanks to #AndyWilkinson for making me read the stacktrace again...
My current project consisting of a war and ejb module, is using a jar (incorperated via maven). This jar contains a CDI component which, when I inject this in the war module it works as expected, but when I inject this in my ejb module I get a NoClassDefFoundError during startup from my WAS 8.5 in eclipse (full profile).
When I start the server first, add the inject later and republish it seems to work. Also when I use Liberty profile it works. Also on Z/os and IPAS it works as expected.
I think it might has something todo with classloading, but have no idea how to solve this properly.
Using Eclipse Neon, WAS 8.5.5.11 full profile , jee6
Project is using java 8 while the component is using java 6
This is the first part of the stacktrace:
[13-9-17 14:54:26:589 CEST] 0000003e InjectionProc W CWNEN0047W: Resource annotations on the fields of the BestelFacade class will be ignored. The annotations could not be obtained because of the exc
eption : Logger
at java.lang.Class.getDeclaredFieldsImpl(Native Method)
Thanks
I found a way to get the job done, but I'm not sure if this is a proper solution or just a workaround while masking the real problem.
When I take a look at the ear module assembly I see in the source column c:/ws/.../jar and in the deploy path lib/jar
when I change the source into /..ear/target/../jar it works
Try setting the <bundleDir>/</bundleDir>
This will place the external jar/ejb not in lib, but in the root.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
...........
<defaultLibBundleDir>lib</defaultLibBundleDir>
<modules>
<jarModule>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<bundleDir>/</bundleDir>
</jarModule>
</modules>
</configuration>
</plugin>
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