package io.takari.maven.plugins.compile.jdt; import io.takari.maven.plugins.exportpackage.ExportPackageMojo; import java.io.File; import java.io.FileOutputStream; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.junit.Assert; import org.junit.Test; public class CompileJdtClasspathVisibilityTest extends AbstractCompileJdtTest { private static final File DEPENDENCY = new File("src/test/projects/compile-jdt-classpath-visibility/test-dependency/test-dependency-0.1.jar"); @Test public void testReference_directDependencyArtifact() throws Exception { // sanity check, references to classes from direct dependencies are allowed File basedir = resources.getBasedir("compile-jdt-classpath-visibility/reference"); MavenProject project = mojos.readMavenProject(basedir); addDependency(project, "dependency", DEPENDENCY); compile(project, true); } @Test public void testReference_indirectDependencyArtifact() throws Exception { // references to classes from indirect dependencies fail the build File basedir = resources.getBasedir("compile-jdt-classpath-visibility/reference"); MavenProject project = mojos.readMavenProject(basedir); addIndirectDependency(project, "dependency", DEPENDENCY); compile(project); mojos.assertMessage(new File(basedir, "src/main/java/reference/Reference.java"), "The type 'DependencyClass' is not API", "test-dependency-0.1.jar"); } @Test public void testReference_accessRulesViolationIgnore() throws Exception { File basedir = resources.getBasedir("compile-jdt-classpath-visibility/reference"); MavenProject project = mojos.readMavenProject(basedir); addDependency(project, "dependency", DEPENDENCY); MavenSession session = mojos.newMavenSession(project); mojos.executeMojo(session, project, "compile", // param("compilerId", "jdt"), // param("transitiveDependencyReference", "ignore"), // param("privatePackageReference", "ignore")); } @Test public void testReference_testCompile() throws Exception { File basedir = resources.getBasedir("compile-jdt-classpath-visibility/reference"); MavenProject project = mojos.readMavenProject(basedir); addDependency(project, "dependency", DEPENDENCY); MavenSession session = mojos.newMavenSession(project); Xpp3Dom[] params = new Xpp3Dom[] {param("compilerId", "jdt"), // param("transitiveDependencyReference", "error"), // param("privatePackageReference", "error")}; mojos.executeMojo(session, project, "compile", params); mojos.executeMojo(session, project, "testCompile", params); } @Test public void testReference_testCompile_internal() throws Exception { File basedir = resources.getBasedir("compile-jdt-classpath-visibility/reference"); MavenProject project = mojos.readMavenProject(basedir); addDependency(project, "dependency", DEPENDENCY); MavenSession session = mojos.newMavenSession(project); Xpp3Dom[] params = new Xpp3Dom[] {param("compilerId", "jdt"), // param("transitiveDependencyReference", "error"), // param("privatePackageReference", "error")}; mojos.executeMojo(session, project, "compile", params); // make all main classes internal File exportsFile = new File(basedir, "target/classes/" + ExportPackageMojo.PATH_EXPORT_PACKAGE); exportsFile.getParentFile().mkdirs(); new FileOutputStream(exportsFile).close(); mojos.executeMojo(session, project, "testCompile", params); } @Test public void testIndirectGrandparent() throws Exception { // project -> ParentClass@direct-dependency -> DependencyClass@indirect-dependency File basedir = resources.getBasedir("compile-jdt-classpath-visibility/indirect-grandparent"); MavenProject project = mojos.readMavenProject(basedir); addDependency(project, "direct-dependency", new File(basedir, "test-parent/test-parent-0.1.jar")); addIndirectDependency(project, "indirect-dependency", DEPENDENCY); compile(project, true); } @Test public void testInternalReference() throws Exception { // project references classes that are not exported by the dependency (takari export-package) File basedir = resources.getBasedir("compile-jdt-classpath-visibility/internal-reference"); MavenProject project = mojos.readMavenProject(basedir); addDependency(project, "indirect-dependency", DEPENDENCY); compile(project); mojos.assertMessage(new File(basedir, "src/main/java/reference/Reference.java"), "The type 'DependencyInternalClass' is not API", "test-dependency-0.1.jar"); } @Test public void testInternalReference_testCompile() throws Exception { // project references classes that are not exported by the dependency (takari export-package) File basedir = resources.getBasedir("compile-jdt-classpath-visibility/internal-reference"); MavenProject project = mojos.readMavenProject(basedir); addDependency(project, "indirect-dependency", DEPENDENCY); MavenSession session = mojos.newMavenSession(project); try { mojos.executeMojo(session, project, "testCompile", // param("compilerId", "jdt"), // param("transitiveDependencyReference", "error"), // param("privatePackageReference", "error")); Assert.fail(); } catch (MojoExecutionException expected) { // expected } mojos.assertMessage(new File(basedir, "src/test/java/reference/ReferenceTest.java"), "The type 'DependencyInternalClass' is not API", "test-dependency-0.1.jar"); } @Test public void testInternalReference_dependencyBundle() throws Exception { // project references classes that are not exported by the dependency (bundle manifest) File basedir = resources.getBasedir("compile-jdt-classpath-visibility/internal-reference"); MavenProject project = mojos.readMavenProject(basedir); addDependency(project, "indirect-dependency", new File("src/test/projects/compile-jdt-classpath-visibility/test-dependency-bundle/test-dependency-bundle-0.1.jar")); compile(project); mojos.assertMessage(new File(basedir, "src/main/java/reference/Reference.java"), "The type 'DependencyInternalClass' is not API", "test-dependency-bundle-0.1.jar"); } private void addIndirectDependency(MavenProject project, String string, File file) throws Exception { addDependency(project, string, file, false); } private void compile(MavenProject project) throws Exception { compile(project, false); } private void compile(MavenProject project, boolean throwMojoExecutionException) throws Exception { try { mojos.compile(project, param("transitiveDependencyReference", "error"), param("privatePackageReference", "error")); } catch (MojoExecutionException e) { if (throwMojoExecutionException) { throw e; } } } private static Xpp3Dom param(String name, String value) { Xpp3Dom node = new Xpp3Dom(name); node.setValue(value); return node; } }