policeman-tools / forbidden-apis

Policeman's Forbidden API Checker
Apache License 2.0
321 stars 34 forks source link

"Parsing signatures failed" if class is not found on classpath #242

Closed huxi closed 5 months ago

huxi commented 7 months ago

I'm trying to use the following custom signature file:

@defaultMessage Use org.assertj.core.api.Assertions.assertThatThrownBy with isInstanceOf and hasMessage instead.
org.junit.jupiter.api.Assertions#assertThrows(java.lang.Class,org.junit.jupiter.api.function.Executable)
org.junit.jupiter.api.Assertions#assertThrows(java.lang.Class,org.junit.jupiter.api.function.Executable,java.lang.String)
org.junit.jupiter.api.Assertions#assertThrows(java.lang.Class,org.junit.jupiter.api.function.Executable,java.util.function.Supplier)
org.junit.jupiter.api.Assertions#assertThrowsExactly(java.lang.Class,org.junit.jupiter.api.function.Executable)
org.junit.jupiter.api.Assertions#assertThrowsExactly(java.lang.Class,org.junit.jupiter.api.function.Executable,java.lang.String)
org.junit.jupiter.api.Assertions#assertThrowsExactly(java.lang.Class,org.junit.jupiter.api.function.Executable,java.util.function.Supplier)
org.junit.Assert#assertThrows(java.lang.Class,org.junit.function.ThrowingRunnable)
org.junit.Assert#assertThrows(java.lang.String,java.lang.Class,org.junit.function.ThrowingRunnable)

Unfortunately, this causes the following error:

[ERROR] Failed to execute goal de.thetaphi:forbiddenapis:3.6:check (default) on project dummy: Parsing signatures failed: Class 'org.junit.jupiter.api.Assertions' not found on classpath while parsing signature: org.junit.jupiter.api.Assertions#assertThrows -> [Help 1]

The reason for this is that JUnit is not part of the compile classpath but instead only part of the test compile classpath. As it should be.

Is it reasonable to fail in such a case instead of simply ignoring such a rule? Shouldn't it be a reason for "celebration" instead if the entire class containing a forbidden method can't even be loaded?

This is my first custom signature file so I might also be doing something the wrong way.

Edit:

I've since been able to find the solution. Adding this to the configuration of the Maven plugin results in the desired behavior.

<ignoreSignaturesOfMissingClasses>true</ignoreSignaturesOfMissingClasses>

I found this setting by checking the source of the plugin so I'd consider this a documentation bug.

huxi commented 7 months ago

I'd suggest to add this to the MavenUsage page of the Wiki below the failOnUnsupportedJava property:

        <!--
          If a class is missing while parsing signatures files, all methods
          and fields from this class are silently ignored. This is useful
          in multi-module Maven projects where only some modules have the
          dependency to which the signature file(s) apply.

          This settings prints no warning at all, so verify the signatures
          at least once with full dependencies.
        -->
        <ignoreSignaturesOfMissingClasses>true</ignoreSignaturesOfMissingClasses>

It may make sense to also mention the existence of this option in SignaturesSyntax.

At the moment, it is only mentioned in CliUsage which gave me the hint to check the source.

Thanks for your work on this tool!

uschindler commented 7 months ago

Will update the Wiki pages.

Actually, the whole documentation with all settings/properties is in the documentation package on Maven Central and here: https://jenkins.thetaphi.de/job/Forbidden-APIs/javadoc/check-mojo.html

uschindler commented 5 months ago

I fixed this in the Wiki: https://github.com/policeman-tools/forbidden-apis/wiki/MavenUsage/_compare/36ea3787919e2fe437c64c3c5947f05b08c743a4...db2ba6e75c8a73e0905be0bc4188f8b5965e6973