-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FORGE-2106: Added ClassLoaderFacet to projects addon with tests
- Loading branch information
Showing
3 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
32 changes: 32 additions & 0 deletions
32
projects/api/src/main/java/org/jboss/forge/addon/projects/facets/ClassLoaderFacet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* Copyright 2015 Red Hat, Inc. and/or its affiliates. | ||
* | ||
* Licensed under the Eclipse Public License version 1.0, available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
*/ | ||
|
||
package org.jboss.forge.addon.projects.facets; | ||
|
||
import java.net.URL; | ||
import java.net.URLClassLoader; | ||
|
||
import org.jboss.forge.addon.projects.Project; | ||
import org.jboss.forge.addon.projects.ProjectFacet; | ||
|
||
/** | ||
* A {@link ProjectFacet} with the {@link Project}'s {@link ClassLoader} | ||
* | ||
* @author <a href="ggastald@redhat.com">George Gastaldi</a> | ||
*/ | ||
public interface ClassLoaderFacet extends ProjectFacet | ||
{ | ||
/** | ||
* Returns the {@link URLClassLoader} with the {@link URL}s that this project depends on. | ||
* | ||
* WARNING: Remember to close this {@link URLClassLoader} when no longer in use. | ||
* <p/> | ||
* Leaving it open could introduce memory leaks. | ||
*/ | ||
URLClassLoader getClassLoader(); | ||
|
||
} |
104 changes: 104 additions & 0 deletions
104
...s/impl/src/main/java/org/jboss/forge/addon/projects/impl/facets/ClassLoaderFacetImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/** | ||
* Copyright 2015 Red Hat, Inc. and/or its affiliates. | ||
* | ||
* Licensed under the Eclipse Public License version 1.0, available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
*/ | ||
|
||
package org.jboss.forge.addon.projects.impl.facets; | ||
|
||
import java.io.File; | ||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.net.URLClassLoader; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.logging.Logger; | ||
|
||
import org.jboss.forge.addon.dependencies.Dependency; | ||
import org.jboss.forge.addon.facets.AbstractFacet; | ||
import org.jboss.forge.addon.facets.constraints.FacetConstraint; | ||
import org.jboss.forge.addon.projects.Project; | ||
import org.jboss.forge.addon.projects.facets.ClassLoaderFacet; | ||
import org.jboss.forge.addon.projects.facets.DependencyFacet; | ||
import org.jboss.forge.addon.projects.facets.PackagingFacet; | ||
import org.jboss.forge.addon.resource.FileResource; | ||
import org.jboss.forge.addon.resource.Resource; | ||
|
||
/** | ||
* Implementation of the {@link ClassLoaderFacet} interface | ||
* | ||
* @author <a href="ggastald@redhat.com">George Gastaldi</a> | ||
*/ | ||
@FacetConstraint(DependencyFacet.class) | ||
class ClassLoaderFacetImpl extends AbstractFacet<Project> implements | ||
ClassLoaderFacet | ||
{ | ||
private static final Logger log = Logger | ||
.getLogger(ClassLoaderFacetImpl.class.getName()); | ||
|
||
@Override | ||
public boolean install() | ||
{ | ||
return isInstalled(); | ||
} | ||
|
||
@Override | ||
public boolean isInstalled() | ||
{ | ||
return true; | ||
} | ||
|
||
@Override | ||
public URLClassLoader getClassLoader() | ||
{ | ||
Project project = getFaceted(); | ||
DependencyFacet facet = project.getFacet(DependencyFacet.class); | ||
List<Dependency> effectiveDependencies = facet | ||
.getEffectiveDependencies(); | ||
List<URL> urls = new ArrayList<>(); | ||
// Add project dependencies | ||
for (Dependency dependency : effectiveDependencies) | ||
{ | ||
FileResource<?> artifact = dependency.getArtifact(); | ||
if (artifact != null) | ||
{ | ||
File artifactFile = artifact.getUnderlyingResourceObject(); | ||
try | ||
{ | ||
urls.add(artifactFile.toURI().toURL()); | ||
} | ||
catch (MalformedURLException e) | ||
{ | ||
log.warning("Error while configuring Reflections: " | ||
+ e.getMessage()); | ||
} | ||
} | ||
} | ||
// Add project build | ||
PackagingFacet packagingFacet = project.getFacet(PackagingFacet.class); | ||
Resource<?> finalArtifact = packagingFacet.getFinalArtifact(); | ||
if (!finalArtifact.exists()) | ||
{ | ||
// Force build | ||
finalArtifact = packagingFacet.createBuilder().quiet(true).build(); | ||
} | ||
if (finalArtifact instanceof FileResource) | ||
{ | ||
File artifact = ((FileResource<?>) finalArtifact).getUnderlyingResourceObject(); | ||
try | ||
{ | ||
urls.add(artifact.toURI().toURL()); | ||
} | ||
catch (MalformedURLException e) | ||
{ | ||
log.warning("Error while configuring Reflections: " | ||
+ e.getMessage()); | ||
} | ||
} | ||
// Project Classloader. May introduce memory leaks if not closed properly | ||
URLClassLoader urlClassLoader = URLClassLoader.newInstance(urls.toArray(new URL[urls.size()])); | ||
return urlClassLoader; | ||
} | ||
|
||
} |
85 changes: 85 additions & 0 deletions
85
.../tests/src/test/java/org/jboss/forge/addon/projects/impl/facets/ClassLoaderFacetTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/** | ||
* Copyright 2015 Red Hat, Inc. and/or its affiliates. | ||
* | ||
* Licensed under the Eclipse Public License version 1.0, available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
*/ | ||
|
||
package org.jboss.forge.addon.projects.impl.facets; | ||
|
||
import java.net.URLClassLoader; | ||
import java.util.Arrays; | ||
|
||
import javax.inject.Inject; | ||
|
||
import org.jboss.arquillian.container.test.api.Deployment; | ||
import org.jboss.arquillian.junit.Arquillian; | ||
import org.jboss.forge.addon.parser.java.facets.JavaSourceFacet; | ||
import org.jboss.forge.addon.projects.Project; | ||
import org.jboss.forge.addon.projects.ProjectFacet; | ||
import org.jboss.forge.addon.projects.ProjectFactory; | ||
import org.jboss.forge.addon.projects.facets.ClassLoaderFacet; | ||
import org.jboss.forge.arquillian.AddonDependency; | ||
import org.jboss.forge.arquillian.Dependencies; | ||
import org.jboss.forge.arquillian.archive.ForgeArchive; | ||
import org.jboss.forge.furnace.repositories.AddonDependencyEntry; | ||
import org.jboss.forge.roaster.Roaster; | ||
import org.jboss.forge.roaster.model.source.JavaClassSource; | ||
import org.jboss.shrinkwrap.api.ShrinkWrap; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
|
||
/** | ||
* | ||
* @author <a href="ggastald@redhat.com">George Gastaldi</a> | ||
*/ | ||
@RunWith(Arquillian.class) | ||
public class ClassLoaderFacetTest | ||
{ | ||
@Deployment | ||
@Dependencies({ | ||
@AddonDependency(name = "org.jboss.forge.addon:parser-java"), | ||
@AddonDependency(name = "org.jboss.forge.addon:resources"), | ||
@AddonDependency(name = "org.jboss.forge.addon:maven"), | ||
@AddonDependency(name = "org.jboss.forge.addon:projects") | ||
}) | ||
public static ForgeArchive getDeployment() | ||
{ | ||
ForgeArchive archive = ShrinkWrap | ||
.create(ForgeArchive.class) | ||
.addBeansXML() | ||
.addAsAddonDependencies( | ||
AddonDependencyEntry.create("org.jboss.forge.furnace.container:cdi"), | ||
AddonDependencyEntry.create("org.jboss.forge.addon:projects"), | ||
AddonDependencyEntry.create("org.jboss.forge.addon:parser-java") | ||
); | ||
|
||
return archive; | ||
} | ||
|
||
@Inject | ||
private ProjectFactory projectFactory; | ||
|
||
@Test | ||
public void testNewClassReflection() throws Exception | ||
{ | ||
Project project = projectFactory.createTempProject(Arrays | ||
.<Class<? extends ProjectFacet>> asList(JavaSourceFacet.class)); | ||
JavaSourceFacet facet = project.getFacet(JavaSourceFacet.class); | ||
Assert.assertNotNull(facet); | ||
JavaClassSource javaClass = Roaster.create(JavaClassSource.class).setName("Foo").setPackage("com.example"); | ||
javaClass.addMethod("public static String hello() {return \"Hello\";}"); | ||
facet.saveJavaSource(javaClass); | ||
Assert.assertTrue(project.hasFacet(ClassLoaderFacet.class)); | ||
ClassLoaderFacet classLoaderFacet = project.getFacet(ClassLoaderFacet.class); | ||
try (URLClassLoader classLoader = classLoaderFacet.getClassLoader()) | ||
{ | ||
Assert.assertNotNull(classLoader); | ||
Class<?> clazz = classLoader.loadClass(javaClass.getQualifiedName()); | ||
Assert.assertSame(classLoader, clazz.getClassLoader()); | ||
Assert.assertEquals("Hello", clazz.getMethod("hello").invoke(null)); | ||
} | ||
} | ||
|
||
} |