From 3758f1f7fcf02d5fc7515cc1577adb331f8cc3e9 Mon Sep 17 00:00:00 2001 From: Fred Bricon Date: Fri, 15 Feb 2013 16:40:47 +0100 Subject: [PATCH] JBIDE-13487 : fix errai deployment issues This fix is 3-fold : - tells GPE to generate the errai classes in a WTP friendly folder - removes non-existing sources from build classpath as it provokes NPEs and prevents Dev Mode from running - Refresh Dev Mode generated folders so these resources can be publishes automatically on any WTP server the app is deployed to. The Dev workflow is greatly simplified for the user : * Dev Mode : - deploy app on WTP server - run as > Web Application on external server (fill in url and select entry point) - click on dev mode link to open in browser * Slow mode : - click on Google > GWT Compile - wait - Run as > Run on server - open browser Signed-off-by: Fred Bricon --- .../org.jboss.tools.maven.gwt/META-INF/MANIFEST.MF | 8 +- .../tools/maven/gwt/GWTProjectConfigurator.java | 262 +++++++++++++++------ .../org/jboss/tools/maven/gwt/MavenGWTPlugin.java | 12 +- .../tools/maven/gwt/MavenGwtDebugModeListener.java | 96 ++++++++ 4 files changed, 302 insertions(+), 76 deletions(-) create mode 100644 maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/MavenGwtDebugModeListener.java diff --git a/maven/plugins/org.jboss.tools.maven.gwt/META-INF/MANIFEST.MF b/maven/plugins/org.jboss.tools.maven.gwt/META-INF/MANIFEST.MF index 57fe192..89ddaaf 100644 --- a/maven/plugins/org.jboss.tools.maven.gwt/META-INF/MANIFEST.MF +++ b/maven/plugins/org.jboss.tools.maven.gwt/META-INF/MANIFEST.MF @@ -6,7 +6,8 @@ Bundle-Version: 1.5.0.qualifier Bundle-Activator: org.jboss.tools.maven.gwt.MavenGWTPlugin Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0", org.eclipse.m2e.core;bundle-version="1.0.0", - org.eclipse.core.resources;bundle-version="3.7.100", + org.eclipse.m2e.jdt, + org.jboss.tools.common.model;bundle-version="3.3.0", com.google.gwt.eclipse.core;bundle-version="2.5.0", org.eclipse.jdt.core;bundle-version="3.7.0", org.slf4j.api;bundle-version="1.6.0", @@ -14,7 +15,10 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0", org.eclipse.jface;bundle-version="3.7.0", org.jboss.tools.maven.ui;bundle-version="1.5.0", org.eclipse.ui;bundle-version="3.7.0", - org.jboss.tools.common.model;bundle-version="3.3.0" + org.eclipse.m2e.jdt, + com.google.gwt.eclipse.oophm;bundle-version="3.0.0", + org.eclipse.core.resources, + org.eclipse.debug.core Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: org.jboss.tools.maven.gwt diff --git a/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/GWTProjectConfigurator.java b/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/GWTProjectConfigurator.java index 41bf9e3..b06f958 100644 --- a/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/GWTProjectConfigurator.java +++ b/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/GWTProjectConfigurator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Red Hat, Inc. + * Copyright (c) 2012-2013 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -13,18 +13,25 @@ package org.jboss.tools.maven.gwt; import java.util.ArrayList; import java.util.List; +import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Plugin; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.m2e.core.project.IMavenProjectFacade; import org.eclipse.m2e.core.project.MavenProjectChangedEvent; import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator; import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest; +import org.eclipse.m2e.jdt.IClasspathDescriptor; +import org.eclipse.m2e.jdt.IClasspathEntryDescriptor; +import org.eclipse.m2e.jdt.IJavaProjectConfigurator; import org.jboss.tools.common.model.project.ProjectHome; import org.jboss.tools.maven.ui.Activator; import org.osgi.service.prefs.BackingStoreException; @@ -32,117 +39,228 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gdt.eclipse.core.properties.WebAppProjectProperties; +import com.google.gwt.eclipse.core.compile.GWTCompileSettings; import com.google.gwt.eclipse.core.modules.IModule; import com.google.gwt.eclipse.core.modules.ModuleUtils; import com.google.gwt.eclipse.core.properties.GWTProjectProperties; -public class GWTProjectConfigurator extends AbstractProjectConfigurator { - private static final Logger log = LoggerFactory.getLogger(GWTProjectConfigurator.class); +public class GWTProjectConfigurator extends AbstractProjectConfigurator implements IJavaProjectConfigurator { + private static final String ERRAI_MARSHALLING_SERVER_CLASS_OUTPUT = " -Derrai.marshalling.server.classOutput="; + + private static final Logger log = LoggerFactory + .getLogger(GWTProjectConfigurator.class); public static final String GWT_WAR_MAVEN_PLUGIN_KEY = "org.codehaus.mojo:gwt-maven-plugin"; + + + public void configure(ProjectConfigurationRequest projectConfig, + IProgressMonitor monitor) throws CoreException { + configureInternal(projectConfig.getMavenProjectFacade(), monitor); + } - @Override - public void configure(ProjectConfigurationRequest projectConfig, IProgressMonitor monitor) throws CoreException { - + private void configureInternal(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException { + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); boolean configureGWT = store.getBoolean(Activator.CONFIGURE_GWT); - log.debug("GWT Entry Point Modules configuration is {}",configureGWT ? "enabled" : "disabled"); - if(configureGWT && projectConfig.getMavenProject().getPlugin(GWT_WAR_MAVEN_PLUGIN_KEY)!=null) { - String projectName = projectConfig.getProject().getName(); - IJavaProject javaProject = JavaCore.create(projectConfig.getProject()); - if(javaProject!=null) { - log.debug("Configure Entry Point Modules for GWT Project {}", projectName); - - Plugin pluginConfig = projectConfig.getMavenProject().getPlugin(GWT_WAR_MAVEN_PLUGIN_KEY); + log.debug("GWT Entry Point Modules configuration is {}", + configureGWT ? "enabled" : "disabled"); + if (configureGWT + && facade.getMavenProject().getPlugin( + GWT_WAR_MAVEN_PLUGIN_KEY) != null) { + + IProject project = facade.getProject(); + String projectName = project.getName(); + IJavaProject javaProject = JavaCore.create(project); + if (javaProject != null && javaProject.exists()) { + + Plugin pluginConfig = facade.getMavenProject() + .getPlugin(GWT_WAR_MAVEN_PLUGIN_KEY); + + if (pluginConfig == null) { + //nothing to do + return; + } + log.debug("Configure Entry Point Modules for GWT Project {}", + projectName); List modNames = findModules(pluginConfig, javaProject); try { - GWTProjectProperties.setEntryPointModules(projectConfig.getProject(), modNames); + List oldModNames = GWTProjectProperties.getEntryPointModules(project); + if (oldModNames == null || !oldModNames.equals(modNames)) { + GWTProjectProperties.setEntryPointModules( + project, modNames); + } } catch (BackingStoreException e) { - logError("Exception in Maven GWT Configurator, cannot set entry point modules", e); + logError( + "Exception in Maven GWT Configurator, cannot set entry point modules", + e); + } + + log.debug("Configure Output location for GWT Project {}", + projectName); + IFolder m2ewtpFolder = project.getFolder("target/m2e-wtp/web-resources/"); + IPath fullpath = null; + IFolder outputfolder = null; + if (!runsInplace(pluginConfig) && m2ewtpFolder.exists()) { + fullpath = m2ewtpFolder.getFullPath(); + outputfolder = m2ewtpFolder; + } else { + fullpath = ProjectHome + .getFirstWebContentPath(project); + if (fullpath != null) { + outputfolder = project.getWorkspace().getRoot().getFolder(fullpath); + } + } + if (fullpath == null) { + log.warn("Can't find output folder for project {}. GWT Configuration incomplete", + projectName); + return; } - - log.debug("Configure Output location for GWT Project {}", projectName); try { - IPath webContentPath = ProjectHome.getFirstWebContentPath(projectConfig.getProject()); - if(webContentPath!=null) { - IFolder outputWorkspaceFolder = projectConfig.getProject().getWorkspace().getRoot().getFolder(webContentPath); - WebAppProjectProperties.setLastUsedWarOutLocation(projectConfig.getProject(), outputWorkspaceFolder.getFullPath()); + IPath lastUsedWarOutLocation = WebAppProjectProperties.getLastUsedWarOutLocation(project); + if (!fullpath.equals(lastUsedWarOutLocation)) { + WebAppProjectProperties.setLastUsedWarOutLocation(project, fullpath); } } catch (BackingStoreException e) { - logError("Exception in Maven GWT Configurator, cannot set war output location", e); + logError( + "Exception in Maven GWT Configurator, cannot set war output location", + e); + } + if (isErraiProject(facade)) { + setErraiVmParams(project, outputfolder.getFolder("WEB-INF/classes").getProjectRelativePath().toPortableString()); } } else { - log.debug("Skip configurator for non Java project {}",projectName); + log.debug("Skip configurator for non Java project {}", + projectName); } } } - + + private boolean isErraiProject(IMavenProjectFacade mavenFacade) { + for (Artifact a : mavenFacade.getMavenProject().getArtifacts()) { + if (a.getArtifactId().contains("errai")){ + return true; + } + } + return false; + } + + private void setErraiVmParams(IProject project, String path) { + GWTCompileSettings settings = GWTProjectProperties + .getGwtCompileSettings(project); + if (settings == null) { + settings = new GWTCompileSettings(project); + } + String vmArgs = (settings.getVmArgs() == null) ? "" : settings + .getVmArgs(); + if (!vmArgs.contains(ERRAI_MARSHALLING_SERVER_CLASS_OUTPUT)) { + vmArgs += ERRAI_MARSHALLING_SERVER_CLASS_OUTPUT + path; + settings.setVmArgs(vmArgs); + + try { + GWTProjectProperties.setGwtCompileSettings(project, settings); + } catch (BackingStoreException e) { + logError( + "Exception in Maven GWT Configurator, cannot set VM Parameters for Errai", + e); + } + } + } + @Override - public void mavenProjectChanged(MavenProjectChangedEvent event, IProgressMonitor monitor) throws CoreException { - IPreferenceStore store = Activator.getDefault().getPreferenceStore(); - boolean configureGWT = store.getBoolean(Activator.CONFIGURE_GWT); - if(configureGWT){ - Plugin newConfig = event.getMavenProject().getMavenProject().getPlugin(GWT_WAR_MAVEN_PLUGIN_KEY); - if(newConfig!=null) { - IJavaProject javaProject = JavaCore.create(event.getMavenProject().getProject()); - if(javaProject.exists()) { - List modNames = findModules(newConfig, javaProject); - try { - GWTProjectProperties.setEntryPointModules(event.getMavenProject().getProject(), modNames); - } catch (BackingStoreException e) { - logError("Exception in Maven GWT Configurator, cannot set entry point modules", e); - } - } + public void mavenProjectChanged(MavenProjectChangedEvent event, + IProgressMonitor monitor) throws CoreException { + configureInternal(event.getMavenProject(), monitor); + } + + + private boolean runsInplace(Plugin pluginConfig) { + Xpp3Dom gwtConfig = (Xpp3Dom) pluginConfig.getConfiguration(); + if (gwtConfig != null) { + Xpp3Dom inplaceNode = gwtConfig.getChild("inplace"); + if (inplaceNode != null) { + return Boolean.parseBoolean(inplaceNode.getValue()); } } + return false; } - private List findModules(Plugin pluginConfig, IJavaProject javaProject){ + private List findModules(Plugin pluginConfig, + IJavaProject javaProject) { List modNames = new ArrayList(); - Xpp3Dom gwtConfig = (Xpp3Dom)pluginConfig.getConfiguration(); - - if (gwtConfig!=null) { - Xpp3Dom[] moduleNodes = gwtConfig.getChildren("module"); - if (moduleNodes.length > 0) { - String moduleQNameTrimmed = null; - for (Xpp3Dom mNode : moduleNodes) { - moduleQNameTrimmed = mNode.getValue().trim(); - } - if(moduleQNameTrimmed != null){ - modNames.add(moduleQNameTrimmed); - } - } else { - Xpp3Dom modulesNode = gwtConfig.getChild("modules"); - if (modulesNode != null) { - moduleNodes = modulesNode.getChildren("module"); - for (Xpp3Dom mNode : moduleNodes) { - String moduleQNameTrimmed = mNode.getValue().trim(); - modNames.add(moduleQNameTrimmed); - } - } - } - } - if(modNames.size() == 0){ - IModule[] modules = ModuleUtils.findAllModules(javaProject,false); - modNames = new ArrayList(); + Xpp3Dom gwtConfig = (Xpp3Dom) pluginConfig.getConfiguration(); + + if (gwtConfig != null) { + Xpp3Dom[] moduleNodes = gwtConfig.getChildren("module"); + if (moduleNodes.length > 0) { + String moduleQNameTrimmed = null; + for (Xpp3Dom mNode : moduleNodes) { + moduleQNameTrimmed = mNode.getValue() == null? null : mNode.getValue().trim(); + } + if (moduleQNameTrimmed != null) { + modNames.add(moduleQNameTrimmed); + } + } else { + Xpp3Dom modulesNode = gwtConfig.getChild("modules"); + if (modulesNode != null) { + moduleNodes = modulesNode.getChildren("module"); + for (Xpp3Dom mNode : moduleNodes) { + String moduleQNameTrimmed = mNode.getValue() == null? null : mNode.getValue().trim(); + if (moduleQNameTrimmed != null) { + modNames.add(moduleQNameTrimmed); + } + } + } + } + } + if (modNames.isEmpty()) { + IModule[] modules = ModuleUtils.findAllModules(javaProject, false); for (IModule iModule : modules) { modNames.add(iModule.getQualifiedName()); - log.debug("\t{}",iModule.getQualifiedName()); + log.debug("\t{}", iModule.getQualifiedName()); } } - return modNames; + return modNames; } /** * Report error in logger and eclipse user interface - * @param message - exception context description - * @param e - exception to report + * + * @param message + * - exception context description + * @param e + * - exception to report */ private void logError(final String message, BackingStoreException e) { log.error(message, e); - MavenGWTPlugin.log(message,e); + MavenGWTPlugin.log(message, e); + } + + @Override + public void configureClasspath(IMavenProjectFacade facade, + IClasspathDescriptor classpath, IProgressMonitor monitor) + throws CoreException { + // TODO Auto-generated method stub + + } + + @Override + public void configureRawClasspath(final ProjectConfigurationRequest request, + IClasspathDescriptor classpath, IProgressMonitor monitor) + throws CoreException { + //Remove non existing source classpath entries as it makes Dev Mode crash + classpath.removeEntry(new IClasspathDescriptor.EntryFilter() { + + @Override + public boolean accept(IClasspathEntryDescriptor descriptor) { + if (descriptor.getEntryKind() == IClasspathEntry.CPE_SOURCE) { + IPath p = descriptor.getPath(); + return !request.getProject().getWorkspace().getRoot().getFolder(p).exists(); + } + return false; + } + }); } } diff --git a/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/MavenGWTPlugin.java b/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/MavenGWTPlugin.java index d01a371..e23b54c 100644 --- a/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/MavenGWTPlugin.java +++ b/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/MavenGWTPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Red Hat, Inc. + * Copyright (c) 2012-2013 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -17,6 +17,9 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.service.prefs.BackingStoreException; +import com.google.gwt.eclipse.oophm.model.IWebAppDebugModelListener; +import com.google.gwt.eclipse.oophm.model.WebAppDebugModel; + public class MavenGWTPlugin implements BundleActivator { private static BundleContext context; @@ -25,12 +28,16 @@ public class MavenGWTPlugin implements BundleActivator { return context; } + private IWebAppDebugModelListener listener; + /* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext bundleContext) throws Exception { MavenGWTPlugin.context = bundleContext; + listener = new MavenGwtDebugModeListener(); + WebAppDebugModel.getInstance().addWebAppDebugModelListener(listener); } /* @@ -39,9 +46,10 @@ public class MavenGWTPlugin implements BundleActivator { */ public void stop(BundleContext bundleContext) throws Exception { MavenGWTPlugin.context = null; + WebAppDebugModel.getInstance().removeWebAppDebugModelListener(listener); } - public static void log(String message, BackingStoreException e) { + public static void log(String message, Exception e) { Platform.getLog(MavenGWTPlugin.getContext().getBundle()).log(new Status(IStatus.ERROR,context.getBundle().getSymbolicName(),message)); } diff --git a/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/MavenGwtDebugModeListener.java b/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/MavenGwtDebugModeListener.java new file mode 100644 index 0000000..8c40389 --- /dev/null +++ b/maven/plugins/org.jboss.tools.maven.gwt/src/org/jboss/tools/maven/gwt/MavenGwtDebugModeListener.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2013 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package org.jboss.tools.maven.gwt; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.m2e.core.internal.IMavenConstants; + +import com.google.gdt.eclipse.core.launch.LaunchConfigurationUtilities; +import com.google.gwt.eclipse.oophm.model.BrowserTab; +import com.google.gwt.eclipse.oophm.model.IWebAppDebugModelListener; +import com.google.gwt.eclipse.oophm.model.LaunchConfiguration; +import com.google.gwt.eclipse.oophm.model.Server; +import com.google.gwt.eclipse.oophm.model.WebAppDebugModelEvent; + +/** + * GWT Debug Mode launch configuration listener refreshing the project hierarchy + * to allow automatic publishing of Dev Mode generated files on WTP servers; + * + * @author Fred Bricon + */ +public class MavenGwtDebugModeListener implements IWebAppDebugModelListener { + + @Override + public void browserTabCreated(WebAppDebugModelEvent arg0) { + } + + @Override + public void browserTabNeedsAttention(WebAppDebugModelEvent arg0) { + } + + @Override + public void browserTabRemoved(WebAppDebugModelEvent arg0) { + } + + @Override + public void browserTabTerminated(WebAppDebugModelEvent arg0) { + } + + @Override + public void launchConfigurationLaunchUrlsChanged( + WebAppDebugModelEvent arg0) { + } + + @Override + public void launchConfigurationLaunched( + WebAppDebugModelEvent event) { + } + + + @Override + public void launchConfigurationRemoved( + WebAppDebugModelEvent arg0) { + } + + @Override + public void launchConfigurationRestartWebServerStatusChanged( + WebAppDebugModelEvent arg0) { + try { + LaunchConfiguration lc = arg0.getElement(); + IProject project = LaunchConfigurationUtilities.getProject(lc.getLaunch().getLaunchConfiguration()); + if (project.hasNature(IMavenConstants.NATURE_ID)) { + project.refreshLocal(IResource.DEPTH_INFINITE, null); + } + } catch (CoreException e) { + e.printStackTrace(); + } + } + + @Override + public void launchConfigurationTerminated( + WebAppDebugModelEvent arg0) { + } + + @Override + public void serverCreated(WebAppDebugModelEvent arg0) { + } + + @Override + public void serverNeedsAttention(WebAppDebugModelEvent arg0) { + } + + @Override + public void serverTerminated(WebAppDebugModelEvent arg0) { + } + +} -- 1.8.0.msysgit.0