Running a gradle jersey 2.0 web app without a web.xml in eclipse - eclipse

I have a gradle project that I import in eclipse. The project is a web app and I manage to build and deploy it to the tomcat but the jersey REST services are not being loaded and hence I get 404 when trying to reach these services.
I'm using tomcat7 which has support for servlet-api 3.0.
please note that I'm not using a web.xml. I have a class that extends Application and should load the right classes and set the root for the REST services.
Here's my class:
import java.util.Set;
import javax.ws.rs.core.Application;
#javax.ws.rs.ApplicationPath("api")
public class JerseyApplicationConfig extends Application
{
#Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
addRestResourceClasses(resources);
return resources;
}
private void addRestResourceClasses(Set<Class<?>> resources)
{
resources.add(com.cisco.gemini.LoggingRESTService.class);
}
}
The problem is that this class does not get created by jersey and therefore the REST services are not set up.
Thanks,
Gal
Update:
I managed to solve the problem so I'm posting here the solution for everyone's benefit.
Here's my gradle file that got things working. I can now build and run the services on tomcat7 from Eclipse and the jersey servlets load properly.
Note: I also wanted to be able to run the service from command line (for testing purposes) for this reason I applied the jettyEclipse plugin. The jetty plugin that comes with gradle does not support servlet-api 3.0. this isn't working for me yet (because of some conflict on slf4j which I'm using) but it might work for others.
Thanks,
Gal
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'jetty'
apply plugin: 'eclipse-wtp'
repositories {
mavenCentral()
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath (group: 'com.sahlbach.gradle', name: 'gradle-jetty-eclipse-plugin', version: '1.9.+')
}
}
apply plugin: 'jettyEclipse'
dependencies {
compile 'javax.servlet:javax.servlet-api:3.0.1'
compile 'com.sun.jersey:jersey-server:1.18.1'
compile 'com.sun.jersey:jersey-core:1.18.1'
compile 'com.sun.jersey:jersey-json:1.18.1'
compile 'com.sun.jersey:jersey-servlet:1.18.1'
compile 'javax.ws.rs:jsr311-api:1.1.1'
compile fileTree(dir: 'libs', include: '*.jar')
compile 'org.codehaus.jettison:jettison:1.3.5'
}
eclipse {
wtp {
component {
contextPath = 'MyService'
deployName = 'MyService'
facet {
facet name: 'jst.web', version: '3.0'
facet name: 'java', version: '1.7' }
}
}
}

If you want to make it working from command-line you can try to use gretty plugin - https://github.com/akhikhl/gretty - it supports newer versions of Jetty including Servlet 3.0 compatible versions. Or the other way is to make your application 2.5 compatible: add web.xml and define various components here. I'd prefer the first solution.

Related

How to convert Java Gradle project to Dynamic Web Project?

I am following this article
https://www.linkedin.com/pulse/building-jax-rs-project-eclipse-gradle-neeraj-malhotra
On how to build a JAX-RS project in Eclipse with Gradle
I am using
Eclipse Java EE IDE for Web Developers.
Version: Oxygen.2 Release (4.7.2)
Build id: 20171218-0600
My target runtime is
WildFly Full 11.0.0.Final (WildFly Core 3.0.8.Final)
my gradle build file
apply plugin: 'war'
apply plugin: 'eclipse-wtp'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile "javax.ws.rs:javax.ws.rs-api:2.0.1"
providedCompile "javax.servlet:javax.servlet-api:3.1.0"
}
I can select the required Facets and set target runtimes etc fine.
The Facets I select are
cdi 2.0
dynamic web module 3.1
java 1.8
jax-rs 2.1
Once I have click on Apply & Close the project has no build issues reported.
What I don't like at this point is that the project has two WEB-INF files
one is at the project level, the other is within the WebContent folder where I would expect it.
There is also a web.xml file even though I specifically didn't select to have a web.xml generated.
The real issues start when I refresh my gradle build by right clicking on the gradle.build file and selecting gradle > refresh gradle project.
When the refresh is complete the following facets have been deselected
cdi 2.0
jax-rs 2.1
and my Dynamic Web Module has been downgraded to 2.4 from 3.1
In addition to this I have the following two MARKERS
CDI Core Validator cannot run on project gradle_jax_rs because Validation Builder precedes CDI (Contexts and Dependency Injection) Builder.
EL Validator cannot run on project gradle_jax_rs because Validation Builder precedes JBoss Knowledge Base Builder.
How can I configure my Dynamic Web Project so that it keeps my desired Facets at the level?
What is my gradle.build missing?
UPDATE
So I've tracked down the culprit in Gradle
org.gradle.plugins.ide.eclipse.EclipseWtpPlugin:-
project.getPlugins().withType(WarPlugin.class, new Action<WarPlugin>() {
#Override
public void execute(WarPlugin warPlugin) {
((IConventionAware) task.getFacet()).getConventionMapping().map("facets", new Callable<List<Facet>>() {
#Override
public List<Facet> call() throws Exception {
return Lists.newArrayList(
new Facet(Facet.FacetType.fixed, "jst.java", null),
new Facet(Facet.FacetType.fixed, "jst.web", null),
new Facet(Facet.FacetType.installed, "jst.web", "2.4"),
new Facet(Facet.FacetType.installed, "jst.java", toJavaFacetVersion(project.getConvention().getPlugin(JavaPluginConvention.class).getSourceCompatibility()))
);
}
});
}
});
This results in duplicate jst.web entries in org.eclipse.wst.common.project.facet.core.xml
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="jst.java"/>
<fixed facet="jst.web"/>
<installed facet="jst.web" version="2.4"/>
<installed facet="jst.java" version="1.8"/>
<installed facet="jst.web" version="3.1"/>
</faceted-project>
Why cant Gradle work correctly. Whats hard about building a Dynamic Web Project with the selected facets?
I have upgraded buildship to...
http://download.eclipse.org/buildship/updates/e47/releases/2.x/2.2.1.v20180125-1441
even with this added to my gradle.build it still cannot build the required dynamic web project correctly
eclipse {
wtp {
facet {
facet name: 'java', version: '1.8'
facet name: 'jst.web', version: '3.1'
facet name: 'wst.jsdt.web', version: '1.0'
}
}
}
Found that this clunky hack fixes the duplicate jst.web versions
apply plugin: 'war'
apply plugin: 'eclipse-wtp'
eclipse.wtp.facet {
file {
facet name: 'jst.web', version: '3.1'
def oldJstWebFacet = facets.findAll {
it.name == 'jst.web' && it.version == '2.4'
}
facets.removeAll(oldJstWebFacet)
facet name: 'java', version: '1.8'
facet name: 'jst.cdi', version: '2.0'
facet name: 'jst.jaxrs', version: '2.1'
facet name: 'wst.jsdt.web', version: '1.0'
}
}
repositories {
mavenCentral()
}
dependencies {
compile "javax.ws.rs:javax.ws.rs-api:2.0.1"
providedCompile "javax.servlet:javax.servlet-api:3.1.0"
}
however now I have the following two eclipse error markers
CDI Core Validator cannot run on project Attempt0002 because Validation Builder precedes CDI (Contexts and Dependency Injection) Builder.
EL Validator cannot run on project Attempt0002 because Validation Builder precedes JBoss Knowledge Base Builder.
I can resolve this issue by amending the builder order within eclipse, however as soon as I build my project with Gradle the issue reappears.
The solution I discovered is as follows:-
HACK the gradle build file as follows:-
apply plugin: 'war'
apply plugin: 'eclipse-wtp'
eclipse {
project {
buildCommands.clear();
buildCommand 'org.eclipse.jdt.core.javabuilder'
buildCommand 'org.eclipse.wst.common.project.facet.core.builder'
buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
buildCommand 'org.jboss.tools.jst.web.kb.kbbuilder'
buildCommand 'org.jboss.tools.cdi.core.cdibuilder'
buildCommand 'org.eclipse.wst.validation.validationbuilder'
}
wtp {
facet {
file {
facet name: 'jst.web', version: '3.1'
def oldJstWebFacet = facets.findAll {
it.name == 'jst.web' && it.version == '2.4'
}
facets.removeAll(oldJstWebFacet)
facet name: 'java', version: '1.8'
facet name: 'jst.cdi', version: '2.0'
facet name: 'jst.jaxrs', version: '2.1'
facet name: 'wst.jsdt.web', version: '1.0'
}
}
}
}
repositories {
mavenCentral()
}
dependencies {
compile "javax.ws.rs:javax.ws.rs-api:2.0.1"
providedCompile "javax.servlet:javax.servlet-api:3.1.0"
}
"Accelerate developer productivity" really ????????

Grails 3.1.5, Hibernate 5, on JBoss throw NoSuchMethodError org.jboss.logging.Logger.debugf

In Grails 3.1.5 with Hibernate5 plugin I cannot deploy to JBoss EAP 6.4.0.GA.
I get:
NoSuchMethodError: org.jboss.logging.Logger.debugf(Ljava/lang/String;I)V
I believe the issue is because Hibernate 5 has a dependency on jboss-logging 3 and even though I've included jboss-logging 3 in my build.gradle file, when I deploy to JBoss I think it's still using an earlier version of jboss-logging which does not include the new "f" methods, i.e. debugf().
How can I get a Grails 3 and Hibernate 5 app to deploy successfully on JBoss EAP 6.4.0?
My build.gradle file is:
buildscript {
ext {
grailsVersion = project.grailsVersion
}
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0"
classpath "org.grails.plugins:hibernate5:5.0.4"
classpath "org.grails.plugins:views-gradle:1.0.4"
classpath "org.jboss.logging:jboss-logging:3.3.0.Final"
}
}
version ...
group ...
apply plugin:"eclipse"
apply plugin:"idea"
apply plugin: "war"
apply plugin: "org.grails.grails-web"
apply plugin: "org.grails.grails-gsp"
apply plugin:"asset-pipeline"
apply plugin: "org.grails.plugins.views-json"
ext {
grailsVersion = project.grailsVersion
gradleWrapperVersion = project.gradleWrapperVersion
}
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencyManagement {
imports {
mavenBom "org.grails:grails-bom:$grailsVersion"
}
applyMavenExclusions false
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.springframework.boot:spring-boot-starter-actuator"
provided "org.springframework.boot:spring-boot-starter-tomcat"
testCompile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-dependencies"
compile "org.grails:grails-web-boot"
compile "org.grails.plugins:cache"
compile "org.grails.plugins:scaffolding"
compile "org.grails.plugins:views-json"
compile "org.grails.plugins:hibernate5"
testCompile "org.grails.plugins:hibernate5"
compile "org.hibernate:hibernate-core:5.1.0.Final"
compile "org.hibernate:hibernate-ehcache:5.1.0.Final"
console "org.grails:grails-console"
profile "org.grails.profiles:web:3.1.5"
runtime "org.grails.plugins:asset-pipeline"
runtime "com.h2database:h2"
runtime files('grails-app/lib/ojdbc7.jar', 'grails-app/lib/xdb6.jar')
compile files('grails/src/java')
testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails.plugins:geb"
testRuntime "org.seleniumhq.selenium:selenium-firefox-driver:2.52.0"
testRuntime "org.seleniumhq.selenium:selenium-support:2.52.0"
console "org.grails:grails-console"
runtime "org.jboss.logging:jboss-logging:3.3.0.Final"
}
task wrapper(type: Wrapper) {
gradleVersion = gradleWrapperVersion
}
assets {
minifyJs = false // This will probably break dependency injection in our AngularJs artifacts that use DI.
minifyCss = true
}
JBoss EAP 6.4 uses Hibernate 4.x. I wouldn't advise mixing versions of the JPA provider. You'd likely need to exclude the JPA subsystem from the deployment to ensure Hibernate 4 dependencies don't get included. You might need to explicitly exclude the JPA API dependencies too since EAP 6 is a Java EE 6 container and Hibernate 5 is for JPA 2.1 which is part of Java EE 7.
If you've sorted out those issues then you'll also need to exclude the jboss-logging dependency from being added to your deployment. With EAP 6.4 you can set an attribute in the logging subsystem which will affect all deployments. Change the add-logging-api-dependencies attribute to false and include the version of jboss-logging required in your deployment.
/subsystem=logging:write-attribute(name=add-logging-api-dependencies, value=false)
If you want only a single deployment to ignore the dependency, then you could use a jboss-deployment-structure.xml to exclude the dependency or the logging subsystem.

How to setup JUnit testing in Gluon Project with Gradle

I am trying to setup JUnit testing in my Gluon JavaFX Application. I am using the Gluon Eclipse Plugin with Gradle and Java 8.
My build.gradle file looks like this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.0.0-b10'
}
}
apply plugin: 'org.javafxports.jfxmobile'
repositories {
jcenter()
}
dependencies {
compile 'com.gluonhq:ignite-dagger:1.0.0'
compile 'org.elasticsearch:elasticsearch:1.6.0'
compile 'ch.qos.logback:logback-classic:1.1.5'
testCompile 'junit:junit:4.12'
}
mainClassName = 'com.me.MyApplication'
jfxmobile {
android {
manifest = 'src/android/AndroidManifest.xml'
}
ios {
infoPList = file('src/ios/Default-Info.plist')
}
}
Resolving the dependency is no problem, but when running the 'test' task, gradle throws an error like this:
When running gradle with java 8, you must set the path to the old jdk, either with property retrolambda.oldJdk or environment variable JAVA6_HOME/JAVA7_HOME
Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-2.2.1-all.zip'.
I already tried to add the retrolambda plugin to gradle according to the plugin's README on GitHub, but it doesn't work so far. Could someone tell me what to do to configure my Gluon project so that I am able to run my JUnit tests with Gradle?
Some important addidtions:
For the plugin version it says: Gluon Tools 1.0.0.201508201514
I think I fogot to mention that I want to use Dagger dependency injection with Gluon Ignite which might be the real problem in my case as it requires Java 8 and might conflict with javafxports or something else. However, I'm not able to make full sense of the various error messages I've seen.
My tests are empty, but they aren't even run, because it fails before.
Your problem seems like a retroLambda configuration issue. If you go through the configuration page for the plugin, it states that if you don't have an environment variable set for JAVA6_HOME or JAVA7_HOME than you need to explicitly define oldJdk for the plugin to work properly.

Gradle custom plugin's build throws "unable to resolve class"

I'm trying to build a gradle custom plugin that in turn depends on other plugin. In particular, the plugin depends on com.bmuschko.docker-remote-api plugin (that again depends on java library com.github.docker-java:docker-java:2.1.1).
So I tried with the following gradle.build file
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'com.bmuschko.docker-remote-api'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.bmuschko:gradle-docker-plugin:2.6.1'
}
}
group = 'com.example'
version = '1.0'
dependencies {
compile gradleApi()
compile localGroovy()
compile group: 'com.github.docker-java', name: 'docker-java', version: '2.1.1'
}
and the following plugin file:
package com.example.build
import org.gradle.api.Project
import org.gradle.api.Plugin
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
class BndPlugin implements Plugin<Project> {
#Override
void apply(Project project) {
task buildDockerImage(type: DockerBuildImage) {
println file("${projectDir}/docker/")
}
}
}
but what I get with gradle build is just the error
unable to resolve class com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
Question: how to properly manage custom plugin's dependencies?
You can get the full plugin project on github.
If you're going to use classes from the plugin, as opposed to just applying it, you should also include the plugin binaries as compile dependency in your lower dependencies section.

Using gradle to generate eclipse projects for EJB Module

I want to generate project and settings for a EAR project, a EJB client jar and a EJB module but i was not able to insert new facets to the eclipseWtp task, tried many combinations based on the documentation on gradle website.
tried things like the following and always got Premature end of file error.
eclipseWtp {
beforeConfigured { wtp ->
wtp.facets.add(new Facet('jst.ejb','3.1'))
}
}
eclipseWtp {
facet(['name':'jst.ejb','version':'3.1'])
}
Make sure that both war and eclipse plugins are applied on the project. Then it will work correctly, eg.:
apply plugin: 'war'
apply plugin: 'eclipse'
eclipseWtp.facet(name: 'jst.ejb', version: '3.1')