Need help determining why EAR built with Gradle will not run when deployed with Eclipse(RAD)/Buildship

buildship
eclipse

(Justin McElroy) #1

I’m new to Gradle, and am attempting to use Eclipse(IBM Rational Application Developer) to deploy a simple “Hello World” JSR-286 portlet built using Spring MVC and Gradle (with Buildship) on my local WebSphere Portal installation.

I have one “Hello World” portlet using Spring MVC that doesn’t use Gradle, and it works fine. I can right-click on my Portal server in RAD, choose “Add and Remove”, move my application over to publish to Portal, and it publishes and runs fine, showing my Hello World message.

I have another “Hello World” portlet that uses Spring MVC and Gradle (with Buildship plugin), that is virtually identical to the non-Gradle portlet (with the exception of Gradle/Buildship). If I right-click on my Portal server in RAD and choose “Add and Remove” and move my application over to publish, it publishes fine (or at least without error), but in Portal it always shows "
This portlet is temporarily disabled." If instead of deploying through RAD, I use gradle to build the EAR file, I can deploy that EAR to Portal through the admin console and it works fine. So there seems to be something with deploying through RAD that is not working right, but I’m having a really hard time pinpointing what the root cause is or how to fix it.

Looking at the logs, I see two possible indicators. First, in the FFDC WebSphere_Portal_Exception.log, I see this:

3 1 11/1/18 7:50:29:353 EDT 11/1/18 7:50:29:353 EDT java.security.PrivilegedActionException com.ibm.ws.portletcontainer.pcinvoker.PortletInvokerImpl.invokeRender 72

And then in the corresponding FFDC log written at the same time, I see this:

[11/1/18 7:50:29:354 EDT] FFDC Exception:java.security.PrivilegedActionException SourceId:com.ibm.ws.portletcontainer.pcinvoker.PortletInvokerImpl.invokeRender ProbeId:72 Reporter:com.ibm.ws.portletcontainer.pcinvoker.PortletInvokerImpl@d0f32d54 java.security.PrivilegedActionException: com.ibm.wsspi.portletcontainer.InvalidPortletWindowIdentifierException: Context path cannot be found: /JustinGradleTest

So that seems to be a pretty good indicator that the cause of my problem is the context root cannot be found for the application, which makes sense why it’s saying “This portlet is temporarily disabled.” But I don’t know what’s causing it to not find a context root.

The second indicator happens during the publish, when this is written to the SystemOut.log:

[11/1/18 7:49:59:967 EDT] 00000160 wtp I org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.Ear50NoDDImportStrategyImpl loadDeploymentDescriptor EAR [ /mnt/disks/mcelroyj/workspaces/Portal/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/JustinGradleTestEAR ] Module [ JustinGradleTest.war ] [ Web Module [ org.eclipse.jst.j2ee.application.internal.impl.WebModuleImpl@95d4ff8d ] URI [ JustinGradleTest.war ] Alt DD [ null ] Context Root [ null ] ] handled as loose archive [ com.ibm.etools.commonarchive.impl.WARFileImpl@29f9b071 (URI: JustinGradleTest.war, lastModified: 0, size: 0, directoryEntry: <unset>, originalURI: JustinGradleTest.war) (types: null) ]

I’m guessing this is a log being written from the gradle eclipse-wpt plugin. The “Context Root [null]” line is kind of a red flag to me, because it seems to match what I’m seeing in WebSphere’s FFDC log. But I’m not sure what is causing it.

My directory structure is flat, with the EAR and war project on the same level:

  • JustinGradleTestEAR
    ** build.gradle file
    ** settings.gradle file
  • JustinGradleTestWAR
    ** build.gradle file
    ** WEBContent/WEB-INF (where web.xml, and portlet and spring files are stored)
    ** src (where hello world servlet is stored)

Here is the settings.gradle file in the EAR project:

rootProject.name = 'JustinGradleTestEAR' includeFlat 'JustinGradleTest'

Here is the build.gradle file in the WAR project:

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java Library project to get you started.
 * For more details take a look at the Java Libraries chapter in the Gradle
 * user guide available at https://docs.gradle.org/4.10.2/userguide/java_library_plugin.html
 */

plugins {    
    id 'war'
    id 'java'
    id 'eclipse'
}

project.webAppDirName = 'WebContent'

configurations {
    war {}
}

artifacts {
    war tasks.war
}

dependencies {
	
	// This dependency is used internally, and not exposed to consumers on their own compile classpath.
	compileOnly 'org.springframework:spring-context:4.1.5.RELEASE'
	compileOnly 'org.springframework:spring-web:4.1.5.RELEASE'
	compileOnly 'org.springframework:spring-webmvc:4.1.5.RELEASE'
	compileOnly 'org.springframework:spring-webmvc-portlet:4.1.5.RELEASE'
	
	// Use JUnit test framework
    testImplementation 'junit:junit:4.12'
}

// In this section you declare where to find the dependencies of your project
repositories {
	 mavenCentral()
}

sourceSets {
	main {
		java { srcDirs = ['src'] }
		resources { srcDirs= ['src'] }
	}
}

def javaVersion = JavaVersion.VERSION_1_7;
sourceCompatibility = javaVersion;
targetCompatibility = javaVersion; // defaults to sourceCompatibility

eclipse{
	classpath{
		defaultOutputDir = file('WebContent/WEB-INF/classes')
		
		file.whenMerged { classpath ->
			def src = entries.find { it.path == 'src' }
			src.output = 'WebContent/WEB-INF/classes'
            
            def jre = entries.find { it.path.contains 'org.eclipse.jdt.launching.JRE_CONTAINER' }
            jre.path = 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/WebSphere Portal v8.5 JRE'
            jre.entryAttributes['owner.project.facets'] = 'java'
            
            def wpsV85Container = new org.gradle.plugins.ide.eclipse.model.Container('org.eclipse.jst.server.core.container/com.ibm.etools.portal.runtime.provider.v85/wps.base.v85')
            classpath.entries << wpsV85Container
            wpsV85Container = entries.find { it.path.contains 'com.ibm.etools.portal.runtime.provider.v85/wps.base.v85' }
            wpsV85Container.entryAttributes['owner.project.facets'] = 'jst.web'
            
            def eclipseInternalModuleContainer = new org.gradle.plugins.ide.eclipse.model.Container('org.eclipse.jst.j2ee.internal.module.container')
            classpath.entries << eclipseInternalModuleContainer
            
        }
	}
	project {
		natures 'org.eclipse.jem.workbench.JavaEMFNature'
		natures 'org.eclipse.wst.common.modulecore.ModuleCoreNature'
		natures 'org.eclipse.wst.common.project.facet.core.nature'
		natures 'org.eclipse.jdt.core.javanature'
		natures 'org.eclipse.wst.jsdt.core.jsNature'
	}
	wtp {
		facet {
			facet name:'wst.jstd.web', version:'1.0'
        	facet name:'jst.web', version:'3.0'
        	facet name:'java', version:'1.7'
        	facet name:'jsr.base', version:'2.0'
        	facet name:'jsr.portal', version:'8.5.2'
        	facet name: 'com.ibm.websphere.coexistence.web', version: '8.5' 
    		facet name: 'com.ibm.websphere.extended.web', version: '8.5'
    		
    		file {
				withXml {
					def node = it.asNode()
					node.appendNode('runtime', [name: 'wps.base.v85'])
					node.appendNode ('fixed', [facet: 'jst.web'])
					node.appendNode ('fixed', [facet: 'java'])
					node.appendNode ('fixed', [facet: 'wst.jstd.web'])
				}
       		}
       	}
       	component {
            libConfigurations += [ configurations.compileOnly ]
        }
	}
}

Here is the build.gradle file in the EAR project:

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java Library project to get you started.
 * For more details take a look at the Java Libraries chapter in the Gradle
 * user guide available at https://docs.gradle.org/4.10.2/userguide/java_library_plugin.html
 */

plugins {    
    id 'ear'
    id 'java'
    id 'eclipse'
}

dependencies {
    deploy project(path: ':JustinGradleTest', configuration: "war")
}

// In this section you declare where to find the dependencies of your project
repositories {
	 mavenCentral()
}

eclipse{
	project {
		natures 'org.eclipse.wst.common.modulecore.ModuleCoreNature'
		natures 'org.eclipse.wst.common.project.facet.core.nature'
	}
	wtp {
		facet {
        	facet name:'jst.ear', version:'6.0'
        	facet name: 'com.ibm.websphere.coexistence.ear', version: '8.5' 
    		facet name: 'com.ibm.websphere.extended.ear', version: '8.5'
    		
    		file {
				withXml {
					def node = it.asNode()
					node.appendNode('runtime', [name: 'wps.base.v85'])
					node.appendNode ('fixed', [facet: 'jst.ear'])
				}
       		}
       	}
	}
}

def javaVersion = JavaVersion.VERSION_1_7;
sourceCompatibility = javaVersion;
targetCompatibility = javaVersion; // defaults to sourceCompatibility

It seems to be something with Gradle/Buildship, or my gradle configuration. I noticed when I used Buildship’s Gradle menu option to “Refresh Gradle Project” in RAD, it made a lot of changes to the Eclipse project, and I’ve spent a lot of time trying to make the Eclipse/Gradle project look just like the Eclipse/Non-Gradle project that works, as far as eclipse configuration XML files. But it seems that has not fixed this issue. I’ve been banging my head on this for a few days, so any help/pointers would be much appreciated.

Thank you.


(Justin McElroy) #2

I think I may be onto something. Gradle is changing the context root in org.eclipse.wst.common.component from “.JustinGradleTest” to just “JustinGradleTest”. Thinking if I can setup the gradle eclipse-wpt config to not do that, that may solve my issue…


(Justin McElroy) #3

Yep, that was the problem. I changed my gradle build file to specify the context root as “.JustinGradleTest” instead of its default behavior of making it “JustinGradleTest”, and it’s working now. So the relevant line is the “contextPath” line below:

wtp {
		facet {
		
			facet name:'wst.jstd.web', version:'1.0'
        	facet name:'jst.web', version:'3.0'
        	facet name:'java', version:'1.7'
        	facet name:'jsr.base', version:'2.0'
        	facet name:'jsr.portal', version:'8.5.2'
        	facet name: 'com.ibm.websphere.coexistence.web', version: '8.5' 
    		facet name: 'com.ibm.websphere.extended.web', version: '8.5'
    		
    		file {
				withXml {
					def node = it.asNode()
					node.appendNode('runtime', [name: 'wps.base.v85'])
					node.appendNode ('fixed', [facet: 'jst.web'])
					node.appendNode ('fixed', [facet: 'java'])
					node.appendNode ('fixed', [facet: 'wst.jstd.web'])
				}
       		}
       	}
       	component {
       		contextPath = '.JustinGradleTest'
            libConfigurations += [ configurations.compileOnly ]
        }
	}

(Justin McElroy) #4

I am curious if this is the expected behavior of Gradle/Buildship - to change this file and set the context root without the leading period. The context root is set in other places that weren’t touched:

  • WebContent/WEB-INF/ibm-web-ext.xml in the same web project where org.eclipse.wst.common.component lives
  • META-INF/application.xml in the EAR project

If Gradle/Buildship had changed the context root everywhere, I’m guessing it would have been fine. But to just change it in one of the three places it’s not surprising it caused an issue, and a very difficult issue to figure out, at least for a newcomer to Gradle/Buildship.