Use resteasy multipart provider jboss module in a maven application - multipartform-data

I am developing maven web application, in which I include the Java EE 8 standard API
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
I am deploying to JBoss EAP 7.2.9
In my application, I want to upload files to a JAX-RS Endpoint.
#POST
#Path("{id}/file-upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void uploadFile(#PathParam("id") Long id, #MultipartForm FileMetaData metaData) {}
FileMetaData
public class FileMetaData{
#FormParam("name")
private String name;
#FormParam("type")
private String type;
#FormParam("file")
#PartType("application/octet-stream")
byte[] file;
}
The problem is #MultipartForm is not part of the standard JavaEE 8 API. To use it, I must include the resteasy multipart provider in my pom
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
<version>3.6.1.Final</version>
<scope>provided</scope>
</dependency>
I used the version provided by WildFly 14.0.0 which is the community counterpart of JBoss EAP 7.2.9. However, I am not sure whether this is the correct practice. JBoss EAP uses its own implementation of the module "resteasy-multipart-provider-3.6.1.SP9-redhat-00001.jar", which is located in a private maven repository.
In addition, I am still using the default implementations provided by JBoss for the Java EE APIs (including non-multipart JAX-RS endpoints), as I am not including any other specific dependencies in my pom.
could including the dependency above be a source of conflicts?
is there a way to depend on the module provided by JBoss without being bound to a specific JBoss version?

After more investigations, I found the following: to use a container module (e.g. jboss resteasy) in your application, add the dependency in your pom with scope provided, which means that this dependency will be provided at runtime by the container. Then you will notice that resteasy is not included in your WAR file.
The version implemented by your container is the one used at runtime and not the version you provide in your pom.xml (here 3.6.1.SP9-redhat-00001 and not 3.6.1.Final).
However, your code compiles against the version in pom, which should be less than or equal to the container provided version (assuming that higher versions from the container should always be backward compatible).

Related

What's the correct class to run Apache Camel 3.14.0 from command line?

I set the following pom.xml to use Camel 3.14.0:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.apps</groupId>
<artifactId>MyApp</artifactId>
<version>1.0.0</version>
<name>MyApp Camel component</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-bom</artifactId>
<version>3.14.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-csv</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-sql</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
</dependency>
<!-- DB dependencies -->
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.6.1</version>
<scope>system</scope>
<systemPath>D:\Drivers\hsqldb-2.6.1-jdk8.jar</systemPath>
</dependency>
</dependencies>
</project>
Then I have this command line in Windows to collect dependencies:
C:\Users\Public\apache-maven-3.2.5\bin\mvn -f pom.xml dependency:copy-dependencies
When I run it I get all jars in the destination folder (../build/target/dependency).
And then I get other run.bat file with following:
set CLASSPATH=../build/target/dependency/*;../config/
java -classpath "%CLASSPATH%" org.apache.camel.spring.Main
But when I run it, I get an error saying it can't find Main class. That class is the one used in previous use cases (Camel 2.10.6) and it worked fine. Would you please advise on what's the right class to reference here?
EDIT 1: I found in documentation that Main is now in org.apache.camel.main, so I configured that in run.bat and it's seems to be running. But now it shows the following and the odd thing about this is that it ceased picking the file from the path configured in context.xml. Any ideas?
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
EDIT 2: I looked on the error and found I needed to include dependency
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
It still seems to work (message regarding slf4 is gone) but still won't pick file from path.
Now, reason I decided to move to last LTS version was because I needed to use a component property only available in newer version of Camel than the one I've been using. So I decided to give a shot to latest version, but now I'm stuck with error saying it can't find the class.
I've somewhat used Camel in the past but only based on examples provided by someone else, never from scratch so I'm no expert at all and unfortunately I need to solve this in a hurry. I guess the easiest would be to use a java bean but I'm no java developer so I thought it might be ok using Spring XML DSL. I'm using java 1.8.0_92.
Camel documentation doesn't seem to provide so many details as per spring xml, so any help will be greatly appreciated.
Frameworks and documentation
First and foremost its good to understand that Apache Camel is integration framework, Spring is application framework with probably its most notable feature being dependency injection. Due to this the documentation kinda expects the developer to be familiar with spring-framework and able juggle between camel and spring documentation.
Camel main
Camel-main in the other hand is tool you can use to run camel applications without any framework so it has no knowledge about spring framework. There's camel-spring-main but more on that later.
Spring-boot
When it comes to spring it might be easier to just use spring-boot which you can think of as collection of maven dependencies you can use to auto-configure your spring application with default configurations.
I recommend that you create a new project using camel maven archetype camel-archetype-spring-boot. This should provide you with good starting point and example on how to get started with camel and spring.
To use spring-xml files with camel-spring-boot you can add annotation #ImportResource(classpath:META-INF/spring/camel-context.xml) over your SpringBootApplication class (class annotated with #SpringBootApplication, named MySpringBootApplication when using the template).
Change the path to match the location and name of your xml-file and delete or comment the example RouteBuilder class from the project to prevent it from interrupting with anything.
# You can run spring-boot application using maven
mvn spring-boot:run
# Alternatively you should be able to run it from jar using
java -jar application.jar
Downside for spring-boot is that it'll flood our project with bunch of extra dependencies. For example to just keep the application running the template project uses spring-boot-start-web, spring-boot-starter-undertow and spring-boot-starter-actuator dependencies.
Camel Spring Main
There's also archetype camel-archetype-spring you can use to create camel spring application without spring-boot. It uses the camel-spring-main I mentioned above and can be run using maven with command mvn camel:run.
However I find this archetype a bit lacking. First it lacks visible main class which is inconsistent if you compare it to some camel-archetype-main. Secondly there seems to be problems with its packaging configurations as I didn't find an easy way to run it from jar. Most attempts I tried resulted in ClassNotFoundException for org/apache/camel/spring/Main even tough I had all maven dependencies in place. It runs fine from IDE however.
Convert your project to JAVA-DSL and use camel main
Since your route doesn't seem all that complex you could probably convert it to Java-DSL from XML in minutes and just run it with camel-main without any application framework. There's archetype for this as well called camel-archetype-main.

CXF not using the bus from the Spring config

I have a standalone java application that uses cxf. I have some features to be added into the bus. thus I added a feature (implementing AbstractFeature) and injecting some headers to outgoing messages. The clients to the endpoints are defined in a core module of my project.
This is working pretty well on containers like tomcat etc.. I can see the injection done and my app working expectedly. But when it comes to the standalone java app. The bus again getting configured with the same feature class. But the requests are not going through the bus. Because the injection class is not triggered while I am debugging it.
well the issue was with some missing libraries. CXF runtime frontend jaxws library is the key to get your bus used. for maven; adding below dependency solves the issue
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>

EnableWebSecurity cannot be resolved to a type

The screenshot of error is here.I am new to spring security and was trying to implement this tutorial http://websystique.com/spring-security/angularjs-basic-authentication-using-spring-security/
But my dependencies are not getting resolved as none of the class of prefix org.springframework.security.config.* is getting resolved to a type
I have already included 3 jars:
spring-security-web-3.1.2-RELEASE.jar
spring-security-core-3.1.2-RELEASE.jar
spring-security-config-3.1.2-RELEASE.jar
still the error is coming. Is there any other jar I am missing?
NOTE-I am not using maven
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
As explained in this answer
Spring Security 3.1.3 #EnableWebSecurity
java config support is not released with Spring Security 3.1.2. I suggest to update spring security to a newer version. Download version 3.2.9 and you will find the missing packages.
This is the link to the spring repository:
http://repo.spring.io/release/org/springframework/security/spring-security/3.2.9.RELEASE/

How to control order of deployment (EJB first and then MBeans deployment) in Wildfly 8.2.0 AS

I am migrating an EAR application containing MBeans from JBoss 6 AS to Wildfly 8.2.0 AS. In my EAR application, MBeans depend on EJB before initialization.
In JBoss 6 AS, #DependsOn annotation used in MBean maintained the sequence of the deployment i.e. Dependent EJB gets deployed and then, MBean gets deployed.
In Wildfly 8.2.0, I am trying to implement the same and #DependsOn is not working.
I tried the below in jboss-service.xml to have MBeans deployed only after the deployment of EAR file but this did not happen.
<mbean code="sample.HelloWorldService" name="sample:service=HelloWorld,id=1">
<depends>jboss.j2ee:service=EARDeployment,url='application.ear'</depends>
</mbean>
I also tried #startup in EJB but I cannot control the sequence i.e. 1. EJB deployment 2. MBeans deployment.
Can anyone please help about how to control the order of deployment in Wildfly 8.2.0. I need to deploy EJB first and then MBeans. Many thanks.
Just a comment
About the EJB that you want to get from the MBeans, maybe you are misunderstanding the specificaction of jboss-deployment-structure.xml. It express an initialization dependency between singleton components (even if the related EJB are singleton be aware about possible problems with DependsOn like WLFY-4251).
Workaround
Due to you are working with Jboss/Wildfly Server, you have the option to use the jboss-deployment-structure.xml for specify dependency between modules.
Perhaps, as your are packing all in the same EAR application, you can separate the components into modules, let's say one MBean.sar module that contains the MBeans and other RelatedEJBs.jar module with the EJBs referenced by your MBeans.
Then you define the next dependency of MBeans.sar over RelatedEJBs.jar,
<jboss-deployment-structure>
...
<sub-deployment name="RelatedEJBs.jar">
...
</sub-deployment>
<sub-deployment name="MBeans.sar">
<dependencies>
<!-- Adds a dependency on the ejb jar. This could also be done with a Class-Path entry -->
<module name="deployment.YouApp.ear.RelatedEJBs.jar" />
</dependencies>
</sub-deployment>
</jboss-deployment-structure>
Edit: A useful migration guide to Wildfly.

cxf-xjc-runtime not included in Wildfly

I am using cxf-codegen-plugin version 2.7.13 (same as cxf version of Wildfly). I want to generate toString methods from wsdl so I add the -xjc-Xts argument and the dependency:
<dependency>
<groupId>org.apache.cxf.xjcplugins</groupId>
<artifactId>cxf-xjc-ts</artifactId>
<version>3.0.3</version>
</dependency>
The generated classes use org.apache.cxf.xjc.runtime.JAXBToStringStyle to create the toString methods which is only available in:
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
</dependency>
This dependency is not in the wildfly cxf modules so when I use this dependency with scope "provided" I get the error:
java.lang.ClassNotFoundException: org.apache.cxf.xjc.runtime.JAXBToStringStyle
When I deploy the application together with the dependency I get the following error:
Apache CXF library (cxf-xjc-runtime-2.6.2.jar) detected in ws endpoint deployment; either provide a proper deployment replacing embedded libraries with container module dependencies or disable the webservices subsystem for the current deployment adding a proper jboss-deployment-structure.xml descriptor to it. The former approach is recommended, as the latter approach causes most of the webservices Java EE and any JBossWS specific functionality to be disabled.
What makes it more strange is an article I found:
http://www.objectpartners.com/2010/11/25/leveraging-apache-cxf-and-maven-to-generate-client-side-web-service-bindings/
which mentions that the generated classes use a different class namely:
org.apache.cxf.jaxb.JAXBToStringStyle
Any help will be appreciated.

Resources