javax validation can't find Hibernate Validator in Karaf - maven

I've implemented some code using javax.validation and Hibernate Validator. The unit tests using validation are working fine. The build produces OSGi bundles and features, and runs in Karaf.
When I run my PaxExam integration test, I get "Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath." As far as I can tell, I AM adding it to my classpath. I have a features.xml file that I've been incrementally adding dependencies to. It finally got past Karaf bundle resolution, but now it's failing with an exception with this message:
"Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath."
I would include the stacktrace, but it doesn't look useful to me. Most of it is in my code, junit, and paxexam.
I'm attempting to use version 5.4.1.Final of HV. Note again that the unit tests doing validation are working fine. It took a while to get the dependencies correct to get that far (like using version "3.0.1-b08" of "javax.el".
I've seen some mentions of a "hibernate-validator-osgi-karaf-features" artifact, but I'm not sure if that's relevant. I'm attempting to use both the hibernate-validator artifact and the hibernate-validator-annotation-processor artifact.
I don't know that it's going to matter, but here's an excerpt of my POM dependencies:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>
hibernate-validator-annotation-processor
</artifactId>
<version>5.4.1.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b08</version>
</dependency>
The following is an excerpt of a "features.xml" file from a bundle that is a dependency (by feature) of the bundle containing the test class:
<bundle start-level="100">wrap:mvn:javax.validation/validation-api/1.1.0.Final$Bundle-Name=javax.validation&Bundle-SymbolicName=javax.validation&Bundle-Version=1.1.0.Final</bundle>
<bundle>mvn:org.hibernate/hibernate-validator/5.4.1.Final</bundle>
<bundle start-level="100">wrap:mvn:org.hibernate/hibernate-validator-annotation-processor/5.4.1.Final$Bundle-Name=hibernate-validator-annotation-processor&Bundle-SymbolicName=hibernate-validator-annotation-processor&Bundle-Version=5.4.1.Final</bundle>
What else can I do at this point?
Update:
I've made some changes according to the answer that refers to the "hibernate-validator-osgi-karaf-features" artifact, but I'm now getting a different unexpected error.
In the pom dependencies I added the following:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>
hibernate-validator-osgi-karaf-features
</artifactId>
<version>5.4.1.Final</version>
<type>pom</type>
</dependency>
In the base features.xml file that is referred to by the features.xml file in my module, I removed the annotation-processor, and added this:
<bundle>wrap:mvn:org.hibernate/hibernate-validator-osgi-karaf-features/5.4.1.Final$Bundle-Name=hibernate-validator-osgi-karaf-features&Bundle-SymbolicName=hibernate-validator-osgi-karaf-features&Bundle-Version=5.4.1.Final</bundle>
I tried not having the "wrap:" and everything after the "$", but the result was the same.
When I ran my test, I saw this:
Caused by: shaded.org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact org.hibernate:hibernate-validator-osgi-karaf-features:jar:5.4.1.Final in central (http://repo1.maven.org/maven2/)
at shaded.org.eclipse.aether.connector.basic.ArtifactTransportListener.transferFailed(ArtifactTransportListener.java:39)[7:org.ops4j.pax.url.mvn:2.4.7]
at shaded.org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(BasicRepositoryConnector.java:355)[7:org.ops4j.pax.url.mvn:2.4.7]
at shaded.org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67)[7:org.ops4j.pax.url.mvn:2.4.7]
at shaded.org.eclipse.aether.connector.basic.BasicRepositoryConnector$DirectExecutor.execute(BasicRepositoryConnector.java:581)[7:org.ops4j.pax.url.mvn:2.4.7]
at shaded.org.eclipse.aether.connector.basic.BasicRepositoryConnector.get(BasicRepositoryConnector.java:249)[7:org.ops4j.pax.url.mvn:2.4.7]
at shaded.org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:520)[7:org.ops4j.pax.url.mvn:2.4.7]
at shaded.org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:421)[7:org.ops4j.pax.url.mvn:2.4.7]
... 16 more
It's curious that it says it can't find it in central. I can verify the artifact is my local maven cache, because my build likely copied it there after I added the maven dependency as described above.
Update:
I'm guessing that part of my problem is that this artifact is a POM artifact, not a JAR artifact, but I don't understand how I need to reference it.
Update:
Someone on karaf-user pointed out that I need to reference it as a feature, not a bundle, so I now replaced my bundle references with the following:
<feature>hibernate-validator-osgi-karaf-features</feature>
Along with the following repository definition next to two other repository definitions:
<repository>mvn:org.hibernate/hibernate-validator-osgi-karaf-features/5.4.1.Final/xml/features</repository>
However, after installing the features file and then rerunning my test, it fails with this:
org.osgi.service.resolver.ResolutionException: Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity=usl-fraudcheck; type=karaf.feature; version="[2.5.0.SNAPSHOT,2.5.0.SNAPSHOT]"; filter:="(&(osgi.identity=usl-fraudcheck)(type=karaf.feature)(version>=2.5.0.SNAPSHOT)(version<=2.5.0.SNAPSHOT))" [caused by: Unable to resolve usl-fraudcheck/2.5.0.SNAPSHOT: missing requirement [usl-fraudcheck/2.5.0.SNAPSHOT] osgi.identity; osgi.identity=usl-base; type=karaf.feature [caused by: Unable to resolve usl-base/2.5.0.SNAPSHOT: missing requirement [usl-base/2.5.0.SNAPSHOT] osgi.identity; osgi.identity=hibernate-validator-osgi-karaf-features; type=karaf.feature]]
As I'm used to now, the last identity referenced here is the thing it can't find, unsurprisingly this new feature I'm referencing.
I then verified that the following file exists:
~/.m2/repository/org/hibernate/hibernate-validator-osgi-karaf-features/5.4.1.Final/hibernate-validator-osgi-karaf-features-5.4.1.Final-features.xml
However, I found it curious that it begins with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0"
name="hibernate-validator-osgi-features"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.4.0">
The “name” property of the top-level features element is “hibernate-validator-osgi-features”, not “hibernate-validator-osgi-karaf-features”. Is that a problem?
Update:
I now understand that my features file has to reference a feature named "hibernate-validator", which is defined in that "hibernate-validator-osgi-karaf-features" artifact. That appears to have resolved my Karaf package resolution problems. However, that simply puts me back to my original problem of:
Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
I tried changing the "LogLevel" in my Pax Exam config from WARNING to DEBUG. This gave me a lot more karaf debug output, but it didn't give me any significant info about why HV is not found in the classpath.
Is there some other debugging I can configure, or configuration in Pax Exam, that can help here?

Just take a look at our Karaf integration tests for the 5.4 branch:
https://github.com/hibernate/hibernate-validator/tree/5.4/osgi/integrationtest
We also use Pax Exam. You should be able to make it work if you follow what we did.
BTW, I see you mention the annotation processor in your dependency for the 2nd time, it's not something you need at runtime. The annotation processor is used to check that the annotations you used make sense at compile time. You should only enable it when you build your project.
See the Maven example here: https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-annotationprocessor-commandline .

This solved it for me:
https://access.redhat.com/documentation/en-us/red_hat_jboss_fuse/6.2/html/apache_cxf_development_guide/Validation#Validation-Intro-Resolver
Read from "Configuring the validation provider explicitly in OSGi"
The problem is that in OSGI CXF has trouble to find the provider automatically so you have to resolve manually by passing the hibernate validator as a constructor argument to the CXF Bean Validation Provider.
Hope this helps :)

Related

Dependency listed in pom file not found in deployed project

I asked a question here that I think I may have found the root of. I have a Spring Boot app using a datasource, net.sourceforge.jtds.jdbc.Driver, that is supposed to be included transitively by Spring Boot 2.0.2 with spring-boot-starter-jpa. However, when I run
jar tf my.jar | grep jtds
the driver class isn't found (we don't have a maven executable on the server to list the classpath). Everything I do to inspect the classpath reflects that the jar isn't there.
I've done this in 2 scenarios: 1) When I didn't explicitly add the jar to my pom, I got the error reported in my previous post. 2) When I do add it explicitly to the pom, I get this error:
java.lang.IllegalStateException: Cannot load driver class: net.sourceforge.jtds.jdbc.Driver
Can someone tell me what's going on?? I am confounded as to why this class can't be found and loaded.
Please mind, that in the Spring Boot Parent POM the jtds dependency is only included in test scope.
If you want to use classes of this dependency also in your production code, please change the Maven scope to compile.
Ok, the problem was solved by adding the dependency with a runtime scope.
In child pom where jar is packaged, you should have
spring-boot-maven-plugin. and dependency as below:
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
</dependency>
In parent pom :
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>${jtds.version}</version>
</dependency>

Maven: The type cannot be resolved. It is indirectly referenced from required .class files

I changed some existing projects from ant to maven projects.
So far so good.
All projects do have the same groupId.
Theres a project with name "ServerBase" and artifactId "server-base".
Within this project theres an abstract class "BaseService" which defines a logger via:
import org.jboss.logging.Logger;
[...]
protected Logger log = Logger.getLogger(this.getClass());
Theres another project with name "Server" and artifactId "server".
Within this project theres a class ConfigurationDAOImpl extending the BaseService-Class above.
Within ConfigurationDAOImpl the logger log is used for creating some outputs.
Within the "Server"'s POM file I have declared:
<dependency>
<groupId>com.tcom.amadeus</groupId>
<artifactId>server-base</artifactId>
<version>${project.version}</version>
</dependency>
Under BuildPath the dependency is shown very nice under MavenDependencies. I removed the old dirct/natural/ant-dependency from build path before.
If I remove it I am getting very much errors about missing classes etc.
But although I do have this dependency I am getting the followin error in eclipse (under tab markers):
The type org.apache.commons.logging.Log cannot be resolved. It is indirectly referenced from required .class files
Resource: ConfigurationDAPImpl.java
Path: /Server/src/main/...
Location: Line 24
Type: Java Problem
I tried removing the dependency and add it again but without any luck.
Both projects do refer to JAVA 1.8.
Both projects have been build with targets clean an package multiple times.
Both projects have been updated by Righclick or pressing F5.
I am using Eclipse Version: Neon.1a Release (4.6.1)
I am using apache-maven-3.3.9
I am using m2e Plugin.
Any further help would be grateful.
Thanks in advance.
There are two ways to 'solve' this:
1)
explicitly add the required dependency within the server-projects pom-file:
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
2)
change the scop of the required dependency within the server-base-projects pom file from up to now 'provide' to 'compile' or erase the scope tag at all such that the default scope is used by maven (which I guess is 'compile')
old:
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
new:
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<scope></scope>
</dependency>
or:
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>
Some background to this from documentation:
http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies
provided This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example,
when building a web application for the Java Enterprise Edition, you
would set the dependency on the Servlet API and related Java EE APIs
to scope provided because the web container provides those classes.
This scope is only available on the compilation and test classpath,
and is not transitive.
Thanks all.
It looks like apache logging library is not brought transitively from your server-base project. Check if in project server under MavenDependencies you see commons-logging (apache logging) jar. If not, then add this as your maven dependency in server-base project.
Repeat the above for all jars that server-base depends on.

are maven dependency exclusions necessary when using spring (mvc) + hadoop + hive?

I have a web app working great. Tried to connect to hadoop using hive. Tests work fine, but I can't run the web app. I get an error from transitive maven dependencies on hadoop-core bringing in j2ee jars that override Tomcat and mess up when trying to run the web app (specifically in loading the context).
Foolishly I thought maybe if I just use Spring Data built for CDH5 they would have covered all that. No such luck. I was following their docs here: https://github.com/spring-projects/spring-hadoop/wiki/Build-with-Cloudera-CDH5
Here's my current POM:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-hadoop</artifactId>
<version>2.0.4.RELEASE-cdh5</version>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>${hive.version}</version>
<scope>runtime</scope>
</dependency>
Here is the error:
SEVERE: Servlet.service() for servlet [jsp] in context with path [] threw exception [java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;] with root cause
java.lang.AbstractMethodError: javax.servlet.jsp.JspFactory.getJspApplicationContext(Ljavax/servlet/ServletContext;)Ljavax/servlet/jsp/JspApplicationContext;
at org.apache.jasper.compiler.Validator$ValidateVisitor.<init>(Validator.java:515)
at org.apache.jasper.compiler.Validator.validateExDirectives(Validator.java:1817)
at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:217)
at org.apache.jasper.compiler.Compiler.compile(Compiler.java:373)
I also got this error when building direct from cloudera's repos
I could start stuffing exclusions in there, but that feels hacky, and I'm paranoid about other transitive dependency errors cropping up that I may not know about.
I've pored over the docs and the sample code and pom files here: https://github.com/spring-projects/spring-hadoop-samples/blob/master/hive/pom.xml
They don't seem to have exclusions in their POM files. However, I've seen other people do it, such as here: Spring + Maven + Hadoop
Is that the accepted way to work with these technologies? This is my first time so am seeking some confirmation here. Perhaps I'm missing something?
Is it canonical to simply have exclusions

#Webservice annotation exception on weblogic

I am trying to run my application which contain JAX WS (2.1) Webservice using JDeveloper 11g R2(11.1.2.3.0) in JDK 1.6.0_31-b05. The error is coming from #WebService annotation present on the class.
When I am running the application, I am getting below error,
java.lang.IllegalArgumentException: Argument(s) "type" can't be null.
at com.sun.xml.bind.api.TypeReference.<init>(TypeReference.java:89)
at com.sun.xml.ws.model.RuntimeModeler.processDocWrappedMethod(RuntimeModeler.java:758)
at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:678)
at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:428)
at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:277)
at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:363)
at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:202)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:496)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:539)
at weblogic.wsee.jaxws.JAXWSDeployedServlet.getEndpoint(JAXWSDeployedServlet.java:183)
It seems that embedded Web Logic is using the internal libraries instead of provided one from JDK. The classes RuntimeModeler or TypeReference are present in JDK rt.jar starts with package com.sun.xml.ws.internal. Weblogic is picking these classes from glassfish.jaxb_1.0.0.0_2-1-12.jar & glassfish.jaxws.rt_1.2.0.0_2-1-5.jar, but these jars are not part of my application.
I have already used weblogic.xml with below tag,
<prefer-web-inf-classes>true</prefer-web-inf-classes>
I tried adding jaxws-api.jar & jws-api.jar in DefaultDomain/lib directory, but that didn't work
Any clue how to resolve this exception or how to force weblogic to use jdk runtime classes? The same application work properly on stand alone weblogic.
I had the same problem and found the answer here: http://www.intropro.com/resources/blog/66-argument-s-type-can-t-be-null
In short - the problem appears because you have jaxb-impl in you classpath which overrides WebLogics own jaxb, You may not explicitly refer to this dependency from your pom.xml, but some of your other dependencies do.
In my case I had apache-cxf as maven dependency and it had jaxb 2.1.13 as sub-dependency with scope "compile". All I had to do is exclude this apaches jaxb and add my own dependency with scope "provided" to explicitly use WebLogics jaxb.
in pom.xml it looked like this:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.2</version>
<exclusions>
<exclusion>
<artifactId>jaxb-impl</artifactId>
<groupId>com.sun.xml.bind</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<scope>provided</scope>
<version>2.1.13</version>
</dependency>
You can use eclipses "Dependency Hierarchy" tab in pom.xml view or simply command line "mvn dependency:tree" to find out how jaxb-impl made it to your classpath.
In my case, i had a typo in the arguments of the operation, where two arguments had the same webParam name. Modified that and deployed, issue was resolved.
Have you tried listing the correct jar in the manifest class-path: attribute? You could also put the jdk classes in the app and try using a FilteringClassLoader to specify which classes to use from the app rather than system classloader.
http://docs.oracle.com/cd/E15051_01/wls/docs103/programming/classloading.html#wp1097263

NoClassDefFoundError with jetty-maven-plugin

I am getting a:
he Cause java.lang.NoClassDefFoundError Msg:net/spy/memcached/MemcachedClient
When executing jetty:run -e in eclipse. Why isn't this dependency being added into the classpath?
Which classpath do you expect it to be added to? If something in your project is trying to load it, ensure you have a project dependency that has that class in it. It looks like it comes from ServiceMix. If you've added something to Jetty itself to make it require that class, then add the dependency to the jetty plugin.
Your code is missing a runtime dependency. I searched Maven Central for the missing class
http://search.maven.org/#search|ga|1|fc%3A%22net.spy.memcached.MemcachedClient%22
Try adding the following to your POM:
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.spymemcached</artifactId>
<version>2.5_2</version>
<packaging>bundle</packaging>
</dependency>
The dependency had a provided scope. Change this.

Resources