├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .travis.yml ├── README.md ├── config ├── FindBugsExcludeFilter.xml ├── pmd-ruleset.xml └── version-rules.xml ├── license.txt ├── pom.xml ├── src ├── it │ ├── brokenFiles │ │ ├── pom.xml │ │ ├── src │ │ │ └── main │ │ │ │ └── resources │ │ │ │ ├── Broken.class │ │ │ │ ├── Broken.java │ │ │ │ └── Broken.xml │ │ └── verify.bsh │ ├── customWebAppResourcesAreConsidered │ │ ├── pom.xml │ │ ├── src │ │ │ └── main │ │ │ │ ├── java │ │ │ │ └── WebAppServlet.java │ │ │ │ └── webapp │ │ │ │ └── WEB-INF │ │ │ │ └── web.xml │ │ └── verify.bsh │ ├── defaultWebAppResourcesAreConsidered │ │ ├── pom.xml │ │ ├── src │ │ │ └── main │ │ │ │ ├── java │ │ │ │ └── WebAppServlet.java │ │ │ │ └── webapp │ │ │ │ └── WEB-INF │ │ │ │ └── web.xml │ │ └── verify.bsh │ ├── help │ │ └── pom.xml │ ├── pom.xml │ ├── reactorProject │ │ ├── emptyProject │ │ │ └── pom.xml │ │ ├── javaProject │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ └── main │ │ │ │ └── java │ │ │ │ └── WebAppServlet.java │ │ ├── pom.xml │ │ ├── secondJavaProject │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ └── main │ │ │ │ └── java │ │ │ │ └── UnusedClassInSecondJavaProject.java │ │ ├── secondReactorProject │ │ │ ├── nestedJavaProject │ │ │ │ ├── pom.xml │ │ │ │ └── src │ │ │ │ │ └── main │ │ │ │ │ └── java │ │ │ │ │ └── UnusedClassInNestedJavaProject.java │ │ │ └── pom.xml │ │ ├── secondWebAppProject │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ └── main │ │ │ │ ├── java │ │ │ │ └── SecondServlet.java │ │ │ │ └── webapp │ │ │ │ └── WEB-INF │ │ │ │ └── web.xml │ │ ├── verify.bsh │ │ └── webAppProject │ │ │ ├── pom.xml │ │ │ └── src │ │ │ └── main │ │ │ └── webapp │ │ │ └── WEB-INF │ │ │ └── web.xml │ └── scatteredHibernate │ │ ├── definitions │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── de │ │ │ └── is24 │ │ │ └── junit │ │ │ └── typedefs │ │ │ └── package-info.java │ │ ├── overriding-definition │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── de │ │ │ └── is24 │ │ │ └── junit │ │ │ └── overriding_typedefs │ │ │ └── package-info.java │ │ ├── pom.xml │ │ ├── usages │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── de │ │ │ └── is24 │ │ │ └── junit │ │ │ └── EntityClass.java │ │ └── verify.bsh ├── main │ └── java │ │ ├── de │ │ └── is24 │ │ │ ├── deadcode4j │ │ │ ├── AnalysisContext.java │ │ │ ├── AnalysisSink.java │ │ │ ├── AnalysisStage.java │ │ │ ├── AnalyzedCode.java │ │ │ ├── Analyzer.java │ │ │ ├── DeadCode.java │ │ │ ├── DeadCodeComputer.java │ │ │ ├── DeadCodeFinder.java │ │ │ ├── IntermediateResult.java │ │ │ ├── IntermediateResults.java │ │ │ ├── Module.java │ │ │ ├── Repository.java │ │ │ ├── Resource.java │ │ │ ├── Utils.java │ │ │ ├── analyzer │ │ │ │ ├── AnalyzerAdapter.java │ │ │ │ ├── AnnotationsAnalyzer.java │ │ │ │ ├── AopXmlAnalyzer.java │ │ │ │ ├── ApacheTilesAnalyzer.java │ │ │ │ ├── ByteCodeAnalyzer.java │ │ │ │ ├── CastorClassesAnalyzer.java │ │ │ │ ├── ClassDependencyAnalyzer.java │ │ │ │ ├── CustomAnnotationsAnalyzer.java │ │ │ │ ├── CustomInterfacesAnalyzer.java │ │ │ │ ├── CustomSuperClassAnalyzer.java │ │ │ │ ├── CustomXmlAnalyzer.java │ │ │ │ ├── ExtendedXmlAnalyzer.java │ │ │ │ ├── FacesConfigXmlAnalyzer.java │ │ │ │ ├── HibernateAnnotationsAnalyzer.java │ │ │ │ ├── IgnoreClassesAnalyzer.java │ │ │ │ ├── InterfacesAnalyzer.java │ │ │ │ ├── JavaFileAnalyzer.java │ │ │ │ ├── JeeAnnotationsAnalyzer.java │ │ │ │ ├── JerseyWebXmlAnalyzer.java │ │ │ │ ├── JettyXmlAnalyzer.java │ │ │ │ ├── LogbackXmlAnalyzer.java │ │ │ │ ├── MainClassAnalyzer.java │ │ │ │ ├── ReferenceToConstantsAnalyzer.java │ │ │ │ ├── ServletContainerInitializerAnalyzer.java │ │ │ │ ├── SimpleXmlAnalyzer.java │ │ │ │ ├── SpringAnnotationsAnalyzer.java │ │ │ │ ├── SpringDataCustomRepositoriesAnalyzer.java │ │ │ │ ├── SpringNamespaceHandlerAnalyzer.java │ │ │ │ ├── SpringWebApplicationInitializerAnalyzer.java │ │ │ │ ├── SpringWebFlowAnalyzer.java │ │ │ │ ├── SpringWebXmlAnalyzer.java │ │ │ │ ├── SpringXmlAnalyzer.java │ │ │ │ ├── SuperClassAnalyzer.java │ │ │ │ ├── TldAnalyzer.java │ │ │ │ ├── TypeErasureAnalyzer.java │ │ │ │ ├── WebXmlAnalyzer.java │ │ │ │ ├── WsddAnalyzer.java │ │ │ │ ├── XmlAnalyzer.java │ │ │ │ ├── javassist │ │ │ │ │ ├── ClassPathFilter.java │ │ │ │ │ └── ClassPoolAccessor.java │ │ │ │ └── webxml │ │ │ │ │ ├── BaseWebXmlAnalyzer.java │ │ │ │ │ ├── Param.java │ │ │ │ │ └── WebXmlHandler.java │ │ │ └── plugin │ │ │ │ ├── CustomXml.java │ │ │ │ ├── DeadCodeLogger.java │ │ │ │ ├── FindDeadCodeMojo.java │ │ │ │ ├── FindDeadCodeOnlyMojo.java │ │ │ │ ├── ModuleGenerator.java │ │ │ │ ├── SubDirectoryFilter.java │ │ │ │ ├── UsageStatisticsManager.java │ │ │ │ └── packaginghandler │ │ │ │ ├── DefaultPackagingHandler.java │ │ │ │ ├── PackagingHandler.java │ │ │ │ ├── PomPackagingHandler.java │ │ │ │ └── WarPackagingHandler.java │ │ │ ├── guava │ │ │ ├── NonNullFunction.java │ │ │ ├── NonNullFunctions.java │ │ │ └── SequentialLoadingCache.java │ │ │ ├── javaparser │ │ │ ├── ImportDeclarations.java │ │ │ └── Nodes.java │ │ │ ├── javassist │ │ │ └── CtClasses.java │ │ │ └── maven │ │ │ ├── UpdateChecker.java │ │ │ └── slf4j │ │ │ ├── AbstractSlf4jMojo.java │ │ │ ├── LoggerForMavenLog.java │ │ │ └── MavenPluginLoggerFactory.java │ │ └── org │ │ └── slf4j │ │ └── impl │ │ └── StaticLoggerBinder.java └── test │ ├── java │ ├── A.java │ ├── AnnotatedClass.java │ ├── B.java │ ├── ClassAnnotatedWithAnnotatedAnnotation.java │ ├── ClassImplementingCloneable.java │ ├── ClassImplementingExternalizable.java │ ├── ClassWithInnerClass.java │ ├── ClassWithTypeArgument.java │ ├── CustomNamespaceHandler.java │ ├── DeadServlet.java │ ├── DependingClass.java │ ├── IndependentClass.java │ ├── MainClass.java │ ├── SingleClass.java │ ├── SomeServletInitializer.java │ ├── SpringXmlBean.java │ ├── SubClassOfAnnotatedClass.java │ ├── SubClassOfClassImplementingExternalizable.java │ ├── SubClassOfSubClassThatShouldBeLive.java │ ├── SubClassThatShouldBeLive.java │ ├── TagClass.java │ ├── TagExtraInfo.java │ ├── TagLibraryValidator.java │ ├── TypeParameterClass.java │ ├── WebAppFilter.java │ ├── WebAppListener.java │ ├── WebAppServlet.java │ └── de │ │ └── is24 │ │ ├── deadcode4j │ │ ├── A_DeadCodeComputer.java │ │ ├── A_DeadCodeFinder.java │ │ ├── A_Module.java │ │ ├── A_Repository.java │ │ ├── A_Utils.java │ │ ├── An_IntermediateResultMap.java │ │ ├── An_IntermediateResultSet.java │ │ ├── An_IntermediateResults.java │ │ ├── AnalysisContextBuilder.java │ │ ├── IntermediateResultMapBuilder.java │ │ ├── ModuleBuilder.java │ │ ├── analyzer │ │ │ ├── AByteCodeAnalyzer.java │ │ │ ├── A_ByteCodeAnalyzer.java │ │ │ ├── A_ClassDependencyAnalyzer.java │ │ │ ├── A_CustomAnnotationsAnalyzer.java │ │ │ ├── A_CustomInterfacesAnalyzer.java │ │ │ ├── A_CustomSuperClassAnalyzer.java │ │ │ ├── A_CustomXmlAnalyzer.java │ │ │ ├── A_HibernateAnnotationsAnalyzer.java │ │ │ ├── A_JavaFileAnalyzer.java │ │ │ ├── A_JerseyWebXmlAnalyzer.java │ │ │ ├── A_LogbackXmlAnalyzer.java │ │ │ ├── A_MainClassAnalyzer.java │ │ │ ├── A_ReferenceToConstantsAnalyzer.java │ │ │ ├── A_ServletContainerInitializerAnalyzer.java │ │ │ ├── A_SimpleXmlAnalyzer.java │ │ │ ├── A_SpringDataCustomRepositoriesAnalyzer.java │ │ │ ├── A_SpringNamespaceHandlerAnalyzer.java │ │ │ ├── A_SpringWebXmlAnalyzer.java │ │ │ ├── A_SpringXmlAnalyzer.java │ │ │ ├── A_SuperClassAnalyzer.java │ │ │ ├── A_TldAnalyzer.java │ │ │ ├── A_TypeErasureAnalyzer.java │ │ │ ├── A_WebXmlAnalyzer.java │ │ │ ├── AnAnalyzer.java │ │ │ ├── An_AnnotationsAnalyzer.java │ │ │ ├── An_ExtendedXmlAnalyzer.java │ │ │ ├── An_IgnoreClassesAnalyzer.java │ │ │ ├── An_InterfacesAnalyzer.java │ │ │ ├── An_XmlAnalyzer.java │ │ │ ├── classdependency │ │ │ │ └── ClassWithInnerClasses.java │ │ │ ├── constants │ │ │ │ ├── AnnotationUsingConstantAsDefault.java │ │ │ │ ├── AnonymousClassUsingConstantOfOuterClassInFieldDirectly.java │ │ │ │ ├── ClassCallingMethodOfStaticallyImportedConstantInField.java │ │ │ │ ├── ClassCallingMethodOnConstantOfImportedClassInField.java │ │ │ │ ├── ClassCallingMethodOnConstantOfNestedClassOfImportedClassInField.java │ │ │ │ ├── ClassUsingConstantInExpression.java │ │ │ │ ├── ClassUsingConstantInField.java │ │ │ │ ├── ClassUsingConstantInMethod.java │ │ │ │ ├── ClassUsingConstantOfImplementedInterfaceInField.java │ │ │ │ ├── ClassUsingConstantOfInnerClassViaStaticImportInField.java │ │ │ │ ├── ClassUsingConstantOfSuperclassInMethod.java │ │ │ │ ├── ClassUsingConstantViaAsteriskStaticImportInField.java │ │ │ │ ├── ClassUsingConstantViaStaticImportInExpression.java │ │ │ │ ├── ClassUsingConstantViaStaticImportInField.java │ │ │ │ ├── ClassUsingConstantViaStaticImportInMethod.java │ │ │ │ ├── ClassUsingConstantViaStaticImportInSwitch.java │ │ │ │ ├── ClassUsingEnumConstantInSwitch.java │ │ │ │ ├── ClassUsingFQConstantInExpression.java │ │ │ │ ├── ClassUsingFQConstantInField.java │ │ │ │ ├── ClassUsingFQConstantInMethod.java │ │ │ │ ├── ClassUsingInnerClassOfConstantInField.java │ │ │ │ ├── ClassUsingInnerClassOfConstantViaAsteriskStaticImportInField.java │ │ │ │ ├── ClassUsingInnerClassOfConstantViaStaticImportInField.java │ │ │ │ ├── ClassUsingNestedConstantOfImplementedInterfaceInField.java │ │ │ │ ├── ClassUsingNestedConstantOfSuperclassInMethod.java │ │ │ │ ├── ClassUsingStaticImportForConstantWithSameFieldNameBeingDeclaredAfterItIsReferencedInMethod.java │ │ │ │ ├── ClassUsingStaticImportForConstantWithSameFieldNameDefinedByInnerClassInMethod.java │ │ │ │ ├── ClassUsingStaticImportForConstantWithSameFieldNameInMethod.java │ │ │ │ ├── ClassUsingStaticImportForConstantWithSameLocalNameInMethod.java │ │ │ │ ├── ClassUsingStaticImportForConstantWithSameLocalNameInStaticInitializer.java │ │ │ │ ├── ClassUsingStaticImportForConstantWithSameLocalNameInSuperiorBlocksMethod.java │ │ │ │ ├── ClassUsingStaticImportForConstantWithSameStaticFieldNameInMethod.java │ │ │ │ ├── ClassUsingStaticMethodInStaticField.java │ │ │ │ ├── ClassUsingStaticMethodOfNestedClassInMethod.java │ │ │ │ ├── ClassUsingStaticMethodOfStaticallyImportedClassInMethod.java │ │ │ │ ├── ClassWithInnerClassNamedLikePotentialTarget.java │ │ │ │ ├── Constants.java │ │ │ │ ├── EnumUsingConstantInField.java │ │ │ │ ├── InnerClassUsingConstantOfImplementedInterfaceInExpression.java │ │ │ │ ├── InnerClassUsingConstantOfOuterClassInFieldDirectly.java │ │ │ │ ├── InnerClassUsingConstantOfOuterClassInFieldViaQualifier.java │ │ │ │ ├── InnerClassUsingNestedConstantOfImplementedInterfaceInExpression.java │ │ │ │ ├── ReferenceToInheritedConstant.java │ │ │ │ ├── ReferenceToInheritedNonConstant.java │ │ │ │ ├── Superclass.java │ │ │ │ └── subpackage │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageInExpression.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageInField.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageInMethod.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageViaAsteriskImportInExpression.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageViaAsteriskImportInField.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageViaAsteriskImportInMethod.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageViaAsteriskStaticImportInField.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageViaStaticImportInExpression.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageViaStaticImportInField.java │ │ │ │ │ ├── ClassUsingConstantOfOtherPackageViaStaticImportInMethod.java │ │ │ │ │ ├── ClassUsingFQConstantOfOtherPackageInExpression.java │ │ │ │ │ ├── ClassUsingFQConstantOfOtherPackageInField.java │ │ │ │ │ ├── ClassUsingFQConstantOfOtherPackageInMethod.java │ │ │ │ │ ├── ClassUsingImportForConstantWithSameFieldNameInMethod.java │ │ │ │ │ ├── ClassUsingImportForConstantWithSameLocalNameInMethod.java │ │ │ │ │ ├── ClassUsingImportForConstantWithSameParameterNameInCatchClause.java │ │ │ │ │ ├── ClassUsingImportForConstantWithSameParameterNameInConstructor.java │ │ │ │ │ ├── ClassUsingImportForConstantWithSameParameterNameInMethod.java │ │ │ │ │ ├── ClassUsingImportForConstantWithSameStaticFieldNameInMethod.java │ │ │ │ │ ├── ClassUsingInnerClassOfConstantOfOtherPackageInField.java │ │ │ │ │ └── EnumUsingImportForConstantWithSameEnumName.java │ │ │ ├── customrepositories │ │ │ │ ├── Foo.java │ │ │ │ ├── FooRepository.java │ │ │ │ ├── FooRepositoryCustom.java │ │ │ │ └── FooRepositoryImpl.java │ │ │ ├── hibernateannotations │ │ │ │ ├── AnotherEntity.java │ │ │ │ ├── AnotherEntityWithGeneratedValue.java │ │ │ │ ├── ClassDefiningGenericGenerator.java │ │ │ │ ├── ClassUsingGeneratedValueAtField.java │ │ │ │ ├── ClassUsingGeneratedValueAtMethod.java │ │ │ │ ├── ClassUsingTypeAtField.java │ │ │ │ ├── ClassUsingTypeAtMethod.java │ │ │ │ ├── ClassUsingTypeWithoutTypeDef.java │ │ │ │ ├── ClassWithDuplicatedTypeDef.java │ │ │ │ ├── ClassWithTypeDef.java │ │ │ │ ├── Entity.java │ │ │ │ ├── EntityWithGeneratedValue.java │ │ │ │ ├── knownStrategies │ │ │ │ │ ├── ClassDefiningGenericGenerator.java │ │ │ │ │ └── package-info.java │ │ │ │ └── package-info.java │ │ │ ├── javassist │ │ │ │ └── A_CtClasses.java │ │ │ ├── typeerasure │ │ │ │ ├── ClassWithAnonymousClasses.java │ │ │ │ ├── ClassWithInheritedType.java │ │ │ │ ├── ClassWithLowerBoundedWildCard.java │ │ │ │ ├── ClassWithTypesThatShouldNotBeRecognized.java │ │ │ │ ├── ClassWithUpperBoundedWildCard.java │ │ │ │ ├── PackageClass.java │ │ │ │ └── TypedArrayList.java │ │ │ └── webxml │ │ │ │ └── A_BaseWebXmlAnalyzer.java │ │ ├── junit │ │ │ ├── AUtilityClass.java │ │ │ ├── AnnotatedAnnotation.java │ │ │ ├── Annotation.java │ │ │ ├── FileLoader.java │ │ │ ├── LoggingRule.java │ │ │ ├── SomeInterface.java │ │ │ └── TempFileRule.java │ │ └── plugin │ │ │ ├── A_DeadCodeLogger.java │ │ │ ├── A_ModuleGenerator.java │ │ │ ├── A_UsageStatisticsManager.java │ │ │ ├── IT_PuttingItAllTogether.java │ │ │ ├── packaginghandler │ │ │ └── A_PackagingHandler.java │ │ │ └── stubs │ │ │ └── ProjectStub.java │ │ ├── guava │ │ ├── A_NonNullFunctions.java │ │ └── A_SequentialLoadingCacheTest.java │ │ ├── javaparser │ │ ├── A_Nodes.java │ │ └── An_ImportDeclarations.java │ │ └── maven │ │ ├── An_UpdateChecker.java │ │ └── slf4j │ │ ├── A_LoggerForMavenLog.java │ │ └── An_AbstractSlf4jMojo.java │ └── resources │ ├── META-INF │ └── spring.handlers │ ├── de │ └── is24 │ │ ├── deadcode4j │ │ ├── analyzer │ │ │ ├── empty.xml │ │ │ ├── jersey.web.xml │ │ │ ├── logback.xml │ │ │ ├── prefixed.xml │ │ │ ├── some.xml │ │ │ ├── spring.web.xml │ │ │ ├── v3-metadata-complete.web.xml │ │ │ ├── v3-metadata-incomplete.web.xml │ │ │ ├── v3-metadata-missing.web.xml │ │ │ └── webxml │ │ │ │ └── web.xml │ │ ├── java8 │ │ │ └── Lambda.java │ │ └── plugin │ │ │ └── projects │ │ │ ├── misconfig.pom.xml │ │ │ └── pom.xml │ │ └── javaparser │ │ └── TypeNameTestClass.java │ ├── nospring.xml │ ├── spring-with-prefix.xml │ ├── spring.xml │ ├── taglib.tld │ └── web.xml └── tools ├── check-code.sh └── update-versions.sh /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | # workflow_dispatch enables manual triggering of the workflow 5 | workflow_dispatch: 6 | schedule: 7 | - cron: '27 1 * * 6' 8 | env: 9 | FAST_EMAIL: ${{ secrets.FAST_EMAIL }} 10 | FAST_USER: ${{ secrets.FAST_USER }} 11 | FAST_TOKEN: ${{ secrets.FAST_TOKEN }} 12 | FAST_HTTPAUTH: ${{ secrets.FAST_HTTPAUTH }} 13 | 14 | jobs: 15 | analyze: 16 | name: Analyze 17 | runs-on: ubuntu-latest 18 | permissions: 19 | actions: read 20 | contents: read 21 | security-events: write 22 | 23 | steps: 24 | - name: S24 static application security testing (SAST) action 25 | uses: scout24/s24-sast-action@v1 26 | with: 27 | languages: java 28 | fast_user: ${{ env.FAST_USER }} 29 | fast_token: ${{ env.FAST_TOKEN }} 30 | java_version: '11' 31 | 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #IDEA files 2 | .idea 3 | *.iml 4 | #Maven files 5 | target 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: java 3 | jdk: 4 | - openjdk6 5 | - openjdk7 6 | - oraclejdk7 7 | - oraclejdk8 8 | env: 9 | - MVN_VERSION=3.0.5 10 | - MVN_VERSION=3.1.1 11 | - MVN_VERSION=3.2.5 12 | - MVN_VERSION=3.3.9 13 | matrix: 14 | exclude: 15 | - jdk: openjdk6 16 | env: MVN_VERSION=3.3.9 17 | 18 | cache: 19 | apt: false 20 | bundler: false 21 | directories: 22 | - $HOME/.m2/repository 23 | before_cache: rm -rf $HOME/.m2/repository/de/is24/mavenplugins/deadcode4j-maven-plugin/ 24 | 25 | before_install: 26 | # install Maven according to build matrix 27 | - MVN_URL=https://archive.apache.org/dist/maven/maven-3/$MVN_VERSION/binaries/apache-maven-$MVN_VERSION-bin.tar.gz 28 | - wget -q -O /tmp/maven.tar.gz $MVN_URL 29 | - tar xzf /tmp/maven.tar.gz 30 | - export M2_HOME=`pwd`/apache-maven-$MVN_VERSION 31 | - export PATH=$M2_HOME/bin:$PATH 32 | # https://github.com/travis-ci/travis-ci/issues/1689 & https://github.com/travis-ci/travis-ci/issues/4613 33 | - export MAVEN_SKIP_RC=true 34 | 35 | install: 36 | #attempt to download all dependencies in the install phase; due to http://jira.codehaus.org/browse/MDEP-82, dependency:go-offline is useless 37 | - mvn -B -U clean verify org.apache.maven.plugins:maven-war-plugin:2.6:help -Dinvoker.skip=true -Dmaven.main.skip=true -Dmaven.plugin.skip=true -Dmaven.test.skip=true -PenableCoverage,travis 38 | # surefire seems to add these dependencies dynamically 39 | - mvn -B org.apache.maven.plugins:maven-dependency-plugin:2.10:get -Dartifact=org.apache.maven.surefire:surefire-junit4:2.17 40 | - mvn -B org.apache.maven.plugins:maven-dependency-plugin:2.10:get -Dartifact=org.apache.maven.surefire:surefire-junit47:2.17 41 | script: mvn -B -o clean verify -PenableCoverage,travis 42 | after_success: mvn -B jacoco:report coveralls:jacoco 43 | 44 | notifications: 45 | webhooks: 46 | urls: 47 | - https://webhooks.gitter.im/e/217ded7d3afc66dca26a 48 | on_success: always 49 | on_failure: always 50 | on_start: false 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deadcode4j [![Latest version](https://maven-badges.herokuapp.com/maven-central/de.is24.mavenplugins/deadcode4j-maven-plugin/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22de.is24.mavenplugins%22%20AND%20a%3A%22deadcode4j-maven-plugin%22) [![Build Status](https://api.travis-ci.org/ImmobilienScout24/deadcode4j.svg?branch=master)](https://travis-ci.org/ImmobilienScout24/deadcode4j) [![Coverage Status](https://img.shields.io/coveralls/ImmobilienScout24/deadcode4j.svg?branch=master)](https://coveralls.io/r/ImmobilienScout24/deadcode4j?branch=master) 2 | 3 | [![Join the chat at https://gitter.im/ImmobilienScout24/deadcode4j](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ImmobilienScout24/deadcode4j?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | 5 | 6 | 7 | *deadcode4j* helps you find code that is no longer used by your application. It is especially useful for cleaning up legacy code. 8 | 9 | As *deadcode4j* is available via the Maven repository, you can simply run 10 | `mvn de.is24.mavenplugins:deadcode4j-maven-plugin:find -Dmaven.test.skip=true` 11 | to analyze your project. 12 | *deadcode4j* will trigger the _package phase_ to be executed for a project (and for all modules listed in a reactor project) before analyzing the output directories. 13 | The output will look something like this: 14 | 15 | [INFO] --- deadcode4j-maven-plugin:2.1.0:find (default-cli) @ someProject --- 16 | [INFO] Analyzed 42 class(es). 17 | [WARNING] Found 2 unused class(es): 18 | [WARNING] de.is24.deadcode4j.Foo 19 | [WARNING] de.is24.deadcode4j.Bar 20 | 21 | Have a look at the [wiki](https://github.com/ImmobilienScout24/deadcode4j/wiki) to get to know the 22 | [features](https://github.com/ImmobilienScout24/deadcode4j/wiki/deadcode4j-v2.1.0%3A-Features), 23 | read about the available [goals](https://github.com/ImmobilienScout24/deadcode4j/wiki/deadcode4j-v2.1.0%3A-Usage), 24 | understand the [configuration](https://github.com/ImmobilienScout24/deadcode4j/wiki/deadcode4j-v2.1.0%3A-Configuration) 25 | or learn *deadcode4j*'s history and principles. 26 | 27 | *deadcode4j* is tested with Maven 3.0.5, 3.1.1, 3.2.5 & 3.3.9. 28 | -------------------------------------------------------------------------------- /config/FindBugsExcludeFilter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /config/pmd-ruleset.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | deadcode4j PMD ruleset 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /config/version-rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | .*-beta 8 | 9 | -------------------------------------------------------------------------------- /src/it/brokenFiles/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | parent 9 | 42 10 | ../pom.xml 11 | 12 | 13 | brokenFiles 14 | 42 15 | jar 16 | This project is used to make sure failing file analysis is a) reported and b) handled gracefully 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/it/brokenFiles/src/main/resources/Broken.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Scout24/deadcode4j/166a87945398d99811f52136883476cf94aa1208/src/it/brokenFiles/src/main/resources/Broken.class -------------------------------------------------------------------------------- /src/it/brokenFiles/src/main/resources/Broken.java: -------------------------------------------------------------------------------- 1 | public class Broken () { 2 | Barbar; 3 | } -------------------------------------------------------------------------------- /src/it/brokenFiles/src/main/resources/Broken.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/it/brokenFiles/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | File buildLog = new File(basedir, "build.log"); 4 | BufferedReader reader = new BufferedReader(new FileReader(buildLog)); 5 | String line; 6 | boolean analysisFailedForFile = false; 7 | while ((line = reader.readLine()) != null) { 8 | if (line.contains("At least one file could not be parsed; analysis may be inaccurate!")) { 9 | analysisFailedForFile = true; 10 | } 11 | } 12 | if (!analysisFailedForFile) { 13 | throw new RuntimeException("Should have warned about analysis issues!"); 14 | } -------------------------------------------------------------------------------- /src/it/customWebAppResourcesAreConsidered/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | parent 9 | 42 10 | ../pom.xml 11 | 12 | 13 | customWebAppResourcesAreConsidered 14 | 42 15 | war 16 | 17 | 18 | 19 | 20 | maven-war-plugin 21 | 22 | ${project.build.directory}/webapp 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/it/customWebAppResourcesAreConsidered/src/main/java/WebAppServlet.java: -------------------------------------------------------------------------------- 1 | public class WebAppServlet { 2 | } 3 | -------------------------------------------------------------------------------- /src/it/customWebAppResourcesAreConsidered/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | aServlet 10 | WebAppServlet 11 | 12 | -------------------------------------------------------------------------------- /src/it/customWebAppResourcesAreConsidered/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | File buildLog = new File(basedir, "build.log"); 4 | BufferedReader reader = new BufferedReader(new FileReader(buildLog)); 5 | String line; 6 | boolean analyzed = false, success = false; 7 | while ((line = reader.readLine()) != null) { 8 | if (line.contains("Analyzed 1 class(es).")) { 9 | analyzed = true; 10 | } else if (line.contains("No unused classes found.")) { 11 | success = true; 12 | } 13 | } 14 | if (!analyzed) { 15 | throw new RuntimeException("Did not analyze any class; this is not expected!"); 16 | } else if (!success) { 17 | throw new RuntimeException("Found unused classes; this is not expected!"); 18 | } -------------------------------------------------------------------------------- /src/it/defaultWebAppResourcesAreConsidered/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | parent 9 | 42 10 | ../pom.xml 11 | 12 | 13 | defaultWebAppResourcesAreConsidered 14 | 42 15 | war 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/it/defaultWebAppResourcesAreConsidered/src/main/java/WebAppServlet.java: -------------------------------------------------------------------------------- 1 | public class WebAppServlet { 2 | } 3 | -------------------------------------------------------------------------------- /src/it/defaultWebAppResourcesAreConsidered/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | aServlet 10 | WebAppServlet 11 | 12 | -------------------------------------------------------------------------------- /src/it/defaultWebAppResourcesAreConsidered/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | File buildLog = new File(basedir, "build.log"); 4 | BufferedReader reader = new BufferedReader(new FileReader(buildLog)); 5 | String line; 6 | boolean analyzed = false, success = false; 7 | while ((line = reader.readLine()) != null) { 8 | if (line.contains("Analyzed 1 class(es).")) { 9 | analyzed = true; 10 | } else if (line.contains("No unused classes found.")) { 11 | success = true; 12 | } 13 | } 14 | if (!analyzed) { 15 | throw new RuntimeException("Did not analyze any class; this is not expected!"); 16 | } else if (!success) { 17 | throw new RuntimeException("Found unused classes; this is not expected!"); 18 | } -------------------------------------------------------------------------------- /src/it/help/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | parent 9 | 42 10 | ../pom.xml 11 | 12 | 13 | help 14 | 42 15 | pom 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/it/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | de.is24.junit 7 | parent 8 | 42 9 | pom 10 | 11 | 12 | 1.6 13 | 1.6 14 | UTF-8 15 | UTF-8 16 | 17 | 18 | 19 | 20 | 21 | 22 | de.is24.mavenplugins 23 | deadcode4j-maven-plugin 24 | @project.version@ 25 | 26 | 27 | 28 | maven-resources-plugin 29 | 3.0.0 30 | 31 | 32 | maven-compiler-plugin 33 | 3.5.1 34 | 35 | 36 | maven-surefire-plugin 37 | 2.17 38 | 39 | 40 | maven-jar-plugin 41 | 3.0.0 42 | 43 | 44 | maven-war-plugin 45 | 2.6 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/it/reactorProject/emptyProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | reactorProject 9 | 42 10 | ../pom.xml 11 | 12 | 13 | reactorProject-emptyProject 14 | 42 15 | jar 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/it/reactorProject/javaProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | reactorProject 9 | 42 10 | ../pom.xml 11 | 12 | 13 | reactorProject-javaProject 14 | 42 15 | jar 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/it/reactorProject/javaProject/src/main/java/WebAppServlet.java: -------------------------------------------------------------------------------- 1 | public class WebAppServlet { 2 | } 3 | -------------------------------------------------------------------------------- /src/it/reactorProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | parent 9 | 42 10 | ../pom.xml 11 | 12 | 13 | reactorProject 14 | 42 15 | pom 16 | 17 | 18 | 19 | 20 | 21 | de.is24.mavenplugins 22 | deadcode4j-maven-plugin 23 | 24 | 25 | secondReactorProject 26 | secondJavaProject 27 | nonExistingProject 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | emptyProject 37 | javaProject 38 | webAppProject 39 | secondWebAppProject 40 | 41 | secondJavaProject 42 | secondReactorProject 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/it/reactorProject/secondJavaProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | reactorProject 9 | 42 10 | ../pom.xml 11 | 12 | 13 | reactorProject-secondJavaProject 14 | 42 15 | jar 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/it/reactorProject/secondJavaProject/src/main/java/UnusedClassInSecondJavaProject.java: -------------------------------------------------------------------------------- 1 | public class UnusedClassInSecondJavaProject { 2 | } 3 | -------------------------------------------------------------------------------- /src/it/reactorProject/secondReactorProject/nestedJavaProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | reactorProject-secondReactorProject 9 | 42 10 | ../pom.xml 11 | 12 | 13 | reactorProject-secondReactorProject-nestedJavaProject 14 | 42 15 | jar 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/it/reactorProject/secondReactorProject/nestedJavaProject/src/main/java/UnusedClassInNestedJavaProject.java: -------------------------------------------------------------------------------- 1 | public class UnusedClassInNestedJavaProject { 2 | } 3 | -------------------------------------------------------------------------------- /src/it/reactorProject/secondReactorProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | reactorProject 9 | 42 10 | ../pom.xml 11 | 12 | 13 | reactorProject-secondReactorProject 14 | 42 15 | pom 16 | 17 | 18 | nestedJavaProject 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/it/reactorProject/secondWebAppProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | reactorProject 9 | 42 10 | ../pom.xml 11 | 12 | 13 | reactorProject-secondWebAppProject 14 | 42 15 | war 16 | 17 | 18 | 19 | de.is24.junit 20 | reactorProject-javaProject 21 | 42 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/it/reactorProject/secondWebAppProject/src/main/java/SecondServlet.java: -------------------------------------------------------------------------------- 1 | public class SecondServlet { 2 | } 3 | -------------------------------------------------------------------------------- /src/it/reactorProject/secondWebAppProject/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | secondServlet 10 | SecondServlet 11 | 12 | -------------------------------------------------------------------------------- /src/it/reactorProject/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | File buildLog = new File(basedir, "build.log"); 4 | BufferedReader reader = new BufferedReader(new FileReader(buildLog)); 5 | String line; 6 | boolean analyzed = false, success = false; 7 | while ((line = reader.readLine()) != null) { 8 | if (line.contains("Analyzed 2 class(es).")) { 9 | analyzed = true; 10 | } else if (line.contains("No unused classes found.")) { 11 | success = true; 12 | } 13 | } 14 | if (!analyzed) { 15 | throw new RuntimeException("Did not analyze the expected number of classes!"); 16 | } else if (!success) { 17 | throw new RuntimeException("Found unused classes; this is not expected!"); 18 | } -------------------------------------------------------------------------------- /src/it/reactorProject/webAppProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | reactorProject 9 | 42 10 | ../pom.xml 11 | 12 | 13 | reactorProject-webAppProject 14 | 42 15 | war 16 | 17 | 18 | 19 | de.is24.junit 20 | reactorProject-javaProject 21 | 42 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/it/reactorProject/webAppProject/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | aServlet 10 | WebAppServlet 11 | 12 | -------------------------------------------------------------------------------- /src/it/scatteredHibernate/definitions/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | scatteredHibernate 9 | 42 10 | ./../pom.xml 11 | 12 | 13 | scatteredHibernate-definitions 14 | ${project.parent.version} 15 | jar 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/it/scatteredHibernate/definitions/src/main/java/de/is24/junit/typedefs/package-info.java: -------------------------------------------------------------------------------- 1 | @TypeDefs({ 2 | @TypeDef(name = "customClass", typeClass = String.class)}) 3 | package de.is24.junit.typedefs; 4 | 5 | import org.hibernate.annotations.TypeDef; 6 | import org.hibernate.annotations.TypeDefs; -------------------------------------------------------------------------------- /src/it/scatteredHibernate/overriding-definition/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | scatteredHibernate 9 | 42 10 | ./../pom.xml 11 | 12 | 13 | scatteredHibernate-overriding-definition 14 | ${project.parent.version} 15 | jar 16 | 17 | 18 | 19 | de.is24.junit 20 | scatteredHibernate-usages 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/it/scatteredHibernate/overriding-definition/src/main/java/de/is24/junit/overriding_typedefs/package-info.java: -------------------------------------------------------------------------------- 1 | @TypeDefs({ 2 | @TypeDef(name = "numberClass", typeClass = Number.class)}) 3 | package de.is24.junit.overriding_typedefs; 4 | 5 | import org.hibernate.annotations.TypeDef; 6 | import org.hibernate.annotations.TypeDefs; -------------------------------------------------------------------------------- /src/it/scatteredHibernate/usages/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | de.is24.junit 8 | scatteredHibernate 9 | 42 10 | ./../pom.xml 11 | 12 | 13 | scatteredHibernate-usages 14 | ${project.parent.version} 15 | jar 16 | 17 | 18 | 19 | de.is24.junit 20 | scatteredHibernate-definitions 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/it/scatteredHibernate/usages/src/main/java/de/is24/junit/EntityClass.java: -------------------------------------------------------------------------------- 1 | package de.is24.junit; 2 | 3 | import javax.persistence.Id; 4 | import org.hibernate.annotations.Type; 5 | 6 | public class EntityClass { 7 | 8 | @Id 9 | @Type(type = "numberClass") 10 | private long id; 11 | 12 | @Type(type = "customClass") 13 | private String content; 14 | 15 | } -------------------------------------------------------------------------------- /src/it/scatteredHibernate/verify.bsh: -------------------------------------------------------------------------------- 1 | import java.io.*; 2 | 3 | File buildLog = new File(basedir, "build.log"); 4 | BufferedReader reader = new BufferedReader(new FileReader(buildLog)); 5 | String line; 6 | boolean analyzed = false, success = false; 7 | while ((line = reader.readLine()) != null) { 8 | if (line.contains("Analyzed 3 class(es).")) { 9 | analyzed = true; 10 | } else if (line.contains("No unused classes found.")) { 11 | success = true; 12 | } 13 | } 14 | if (!analyzed) { 15 | throw new RuntimeException("Did not analyze the expected number of classes!"); 16 | } else if (!success) { 17 | throw new RuntimeException("Found unused classes; this is not expected!"); 18 | } -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/AnalysisStage.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | /** 4 | * Represents the various stages of deadcode4j's analysis process. 5 | * 6 | * @since 2.0.0 7 | */ 8 | public enum AnalysisStage { 9 | GENERAL_SETUP, MODULE_SETUP, FILE_ANALYSIS, DEADCODE_ANALYSIS 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/AnalyzedCode.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import javax.annotation.Nonnull; 4 | import java.util.EnumSet; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | /** 9 | * AnalyzedCode comprises the classes being analyzed as well as the code dependencies. 10 | * 11 | * @since 1.0.0 12 | */ 13 | public class AnalyzedCode { 14 | @Nonnull 15 | private final EnumSet stagesWithExceptions; 16 | @Nonnull 17 | private final Set analyzedClasses; 18 | @Nonnull 19 | private final Map> codeDependencies; 20 | 21 | public AnalyzedCode(@Nonnull EnumSet stagesWithExceptions, 22 | @Nonnull Set analyzedClasses, 23 | @Nonnull Map> codeDependencies) { 24 | this.stagesWithExceptions = stagesWithExceptions; 25 | this.analyzedClasses = analyzedClasses; 26 | this.codeDependencies = codeDependencies; 27 | } 28 | 29 | @Nonnull 30 | public Set getAnalyzedClasses() { 31 | return analyzedClasses; 32 | } 33 | 34 | /** 35 | * Returns a map consisting of code artifacts (typically classes) pointing to their dependencies. 36 | */ 37 | @Nonnull 38 | public Map> getCodeDependencies() { 39 | return codeDependencies; 40 | } 41 | 42 | /** 43 | * Returns the stages for which an exception occurred. 44 | * 45 | * @since 2.0.0 46 | */ 47 | @Nonnull 48 | public EnumSet getStagesWithExceptions() { 49 | return stagesWithExceptions; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/Analyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import javax.annotation.Nonnull; 4 | import java.io.File; 5 | 6 | /** 7 | * An Analyzer analyzes code of all flavours: java classes, spring XML files, web.xml etc. 8 | * 9 | * @since 1.1.0 10 | */ 11 | public interface Analyzer { 12 | 13 | /** 14 | * Perform an analysis for the specified file. 15 | * Results must be reported via the capabilities of the {@link AnalysisContext}. 16 | * 17 | * @since 1.1.0 18 | */ 19 | void doAnalysis(@Nonnull AnalysisContext analysisContext, @Nonnull File fileName); 20 | 21 | /** 22 | * Indicates that all files of a module have been processed. 23 | * This method offers Analyzers the possibility to report dependencies based on a module or store 24 | * {@link de.is24.deadcode4j.IntermediateResult}s. 25 | * 26 | * @since 1.4 27 | */ 28 | void finishAnalysis(@Nonnull AnalysisContext analysisContext); 29 | 30 | /** 31 | * Indicates that all modules have been processed. 32 | * This method offers Analyzers the possibility to report dependencies based on the whole project. 33 | * 34 | * @since 2.0.0 35 | */ 36 | void finishAnalysis(@Nonnull AnalysisSink analysisSink, @Nonnull AnalyzedCode analyzedCode); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/DeadCode.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import javax.annotation.Nonnull; 4 | import java.util.Collection; 5 | import java.util.EnumSet; 6 | 7 | /** 8 | * DeadCode provides the results of the {@link DeadCodeFinder}. 9 | * 10 | * @since 1.0.0 11 | */ 12 | public class DeadCode { 13 | @Nonnull 14 | private final EnumSet stagesWithExceptions; 15 | @Nonnull 16 | private final Collection analyzedClasses; 17 | @Nonnull 18 | private final Collection deadClasses; 19 | 20 | public DeadCode(@Nonnull EnumSet stagesWithExceptions, 21 | @Nonnull Collection analyzedClasses, 22 | @Nonnull Collection deadClasses) { 23 | this.stagesWithExceptions = stagesWithExceptions; 24 | this.analyzedClasses = analyzedClasses; 25 | this.deadClasses = deadClasses; 26 | } 27 | 28 | @Nonnull 29 | public Collection getAnalyzedClasses() { 30 | return this.analyzedClasses; 31 | } 32 | 33 | @Nonnull 34 | public Collection getDeadClasses() { 35 | return this.deadClasses; 36 | } 37 | 38 | /** 39 | * Returns the stages for which an exception occurred. 40 | * 41 | * @since 2.0.0 42 | */ 43 | @Nonnull 44 | public EnumSet getStagesWithExceptions() { 45 | return stagesWithExceptions; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/DeadCodeComputer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import javax.annotation.Nonnull; 4 | import java.util.Collection; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | import static com.google.common.collect.Lists.newArrayList; 9 | import static com.google.common.collect.Sets.newHashSet; 10 | 11 | /** 12 | * The DeadCodeComputer computes the {@link DeadCode} based on {@link AnalyzedCode}. 13 | * 14 | * @since 2.0.0 15 | */ 16 | public class DeadCodeComputer { 17 | 18 | @Nonnull 19 | public DeadCode computeDeadCode(@Nonnull AnalyzedCode analyzedCode) { 20 | Collection deadClasses = determineDeadClasses(analyzedCode); 21 | return new DeadCode(analyzedCode.getStagesWithExceptions(), analyzedCode.getAnalyzedClasses(), deadClasses); 22 | } 23 | 24 | @Nonnull 25 | private Collection determineDeadClasses(@Nonnull AnalyzedCode analyzedCode) { 26 | Set classesInUse = newHashSet(); 27 | for (Iterable usedClasses : analyzedCode.getCodeDependencies().values()) { 28 | for (String clazz : usedClasses) { 29 | classesInUse.add(clazz); 30 | } 31 | } 32 | 33 | List deadClasses = newArrayList(analyzedCode.getAnalyzedClasses()); 34 | deadClasses.removeAll(classesInUse); 35 | return deadClasses; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/IntermediateResult.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | /** 6 | * If an IntermediateResult is put into an {@link AnalysisContext#getCache() analysis context's cache}, 7 | * it will be made available to the analysis context of those modules depending on the module the result belongs to. 8 | * 9 | * @since 2.0.0 10 | */ 11 | public interface IntermediateResult { 12 | 13 | /** 14 | * If a module depends on both module A and B, each providing an intermediate result for the same key, 15 | * the results will be merged by calling this method on A's result using B's result as a parameter.
16 | * Note that if collisions occur, A's results should usually be preferred as A is listed higher in the 17 | * class path.

18 | * It is important that neither result is modified by this call. 19 | * 20 | * @param sibling the IntermediateResult to merge with 21 | * @return a new IntermediateResult instance 22 | * @since 2.0.0 23 | */ 24 | @Nonnull 25 | IntermediateResult mergeSibling(@Nonnull IntermediateResult sibling); 26 | 27 | /** 28 | * If a module depends on module A which in turn depends on module B, both providing an intermediate 29 | * result for the same key, the results will be merged by calling this method on A's result using B's 30 | * result as a parameter.
31 | * Note that if collisions occur, A's results should be preferred as A is listed higher in the class 32 | * path.

33 | * It is important that neither result is modified by this call. 34 | * 35 | * @param parent the IntermediateResult to merge with 36 | * @return a new IntermediateResult instance 37 | * @since 2.0.0 38 | */ 39 | @Nonnull 40 | IntermediateResult mergeParent(@Nonnull IntermediateResult parent); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/Repository.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import javax.annotation.Nonnull; 4 | import java.io.File; 5 | import java.io.FileFilter; 6 | 7 | import static com.google.common.base.Preconditions.checkArgument; 8 | import static org.apache.commons.io.filefilter.TrueFileFilter.TRUE; 9 | 10 | /** 11 | * A Repository represents a directory containing code, resources, configuration, etc. 12 | * along with an optional file filter. 13 | * 14 | * @since 1.2.0 15 | */ 16 | public class Repository { 17 | @Nonnull 18 | private final File directory; 19 | @Nonnull 20 | private final FileFilter fileFilter; 21 | 22 | public Repository(@Nonnull File directory, @Nonnull FileFilter fileFilter) { 23 | checkArgument(directory.isDirectory(), "No valid directory: " + directory); 24 | this.directory = directory; 25 | this.fileFilter = fileFilter; 26 | } 27 | 28 | public Repository(@Nonnull File directory) { 29 | this(directory, TRUE); 30 | } 31 | 32 | @Nonnull 33 | @Override 34 | public String toString() { 35 | return "Repository @" + this.directory; 36 | } 37 | 38 | @Nonnull 39 | public File getDirectory() { 40 | return directory; 41 | } 42 | 43 | @Nonnull 44 | public FileFilter getFileFilter() { 45 | return fileFilter; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/Resource.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import com.google.common.base.Optional; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | * A Resource represents a required artifact/dependency of a Module. 9 | * It can be a mere class path entry or a Module which is part of the analysis. 10 | * 11 | * @since 2.0.0 12 | */ 13 | public abstract class Resource { 14 | 15 | public static Resource of(final File file) { 16 | return new Resource() { 17 | @Override 18 | public Optional getClassPathEntry() { 19 | return Optional.of(file); 20 | } 21 | 22 | @Override 23 | public Optional getReferencedModule() { 24 | return Optional.absent(); 25 | } 26 | }; 27 | } 28 | 29 | public static Resource of(final Module module) { 30 | return new Resource() { 31 | @Override 32 | public Optional getClassPathEntry() { 33 | Repository repository = module.getOutputRepository(); 34 | return repository != null ? Optional.of(repository.getDirectory()) : Optional.absent(); 35 | } 36 | 37 | @Override 38 | public Optional getReferencedModule() { 39 | return Optional.of(module); 40 | } 41 | }; 42 | } 43 | 44 | public abstract Optional getClassPathEntry(); 45 | 46 | public abstract Optional getReferencedModule(); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/AnalyzerAdapter.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import de.is24.deadcode4j.AnalysisSink; 5 | import de.is24.deadcode4j.AnalyzedCode; 6 | import de.is24.deadcode4j.Analyzer; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import javax.annotation.Nonnull; 11 | 12 | /** 13 | * The AnalyzerAdapter implements all non-vital methods defined for an Analyzer with a no-op. 14 | * 15 | * @since 1.4 16 | */ 17 | public abstract class AnalyzerAdapter implements Analyzer { 18 | 19 | protected final Logger logger = LoggerFactory.getLogger(getClass()); 20 | 21 | @Override 22 | public String toString() { 23 | return getClass().getName(); 24 | } 25 | 26 | @Override 27 | public void finishAnalysis(@Nonnull AnalysisContext analysisContext) { 28 | } 29 | 30 | @Override 31 | public void finishAnalysis(@Nonnull AnalysisSink analysisSink, @Nonnull AnalyzedCode analyzedCode) { 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/AopXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes aop.xml files: lists the aspects being referenced.
5 | * This should work for both AspectJ and 6 | * AspectWerkz. 7 | * 8 | * @since 1.5 9 | */ 10 | public final class AopXmlAnalyzer extends SimpleXmlAnalyzer { 11 | 12 | public AopXmlAnalyzer() { 13 | super("_AOP-XML_", "aop.xml", null); 14 | registerClassAttribute("aspect", "class"); 15 | registerClassAttribute("aspect", "name"); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/ApacheTilesAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes Apache Tiles definition XML files: lists the preparer, bean & item 5 | * classes being referenced. 6 | * 7 | * @since 1.5 8 | */ 9 | public final class ApacheTilesAnalyzer extends SimpleXmlAnalyzer { 10 | 11 | public ApacheTilesAnalyzer() { 12 | super("_ApacheTilesXml_", ".xml", "tiles-definitions"); 13 | // http://tiles.apache.org/dtds/tiles-config_3_0.dtd 14 | registerClassAttribute("definition", "preparer"); 15 | // http://tiles.apache.org/dtds/tiles-config_2_1.dtd 16 | // http://tiles.apache.org/dtds/tiles-config_2_0.dtd 17 | registerClassAttribute("bean", "classtype"); 18 | registerClassAttribute("item", "classtype"); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/CastorClassesAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes class files: marks a class as being in use if it directly extends 5 | * org.exolab.castor.xml.util.XMLClassDescriptorImpl. 6 | * 7 | * @since 1.4 8 | */ 9 | public final class CastorClassesAnalyzer extends SuperClassAnalyzer { 10 | 11 | public CastorClassesAnalyzer() { 12 | super("_Castor-GeneratedClass_", "org.exolab.castor.xml.util.XMLClassDescriptorImpl"); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/ClassDependencyAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import javassist.CtClass; 5 | 6 | import javax.annotation.Nonnull; 7 | import java.util.Collection; 8 | 9 | /** 10 | * Analyzes class files: lists the classes a class is depending on. 11 | * 12 | * @since 1.0.0 13 | */ 14 | public class ClassDependencyAnalyzer extends ByteCodeAnalyzer { 15 | 16 | @Override 17 | protected void analyzeClass(@Nonnull AnalysisContext analysisContext, @Nonnull CtClass clazz) { 18 | String className = clazz.getName(); 19 | 20 | @SuppressWarnings("unchecked") 21 | Collection refClasses = clazz.getRefClasses(); 22 | 23 | analysisContext.addAnalyzedClass(className); 24 | analysisContext.addDependencies(className, refClasses); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/CustomAnnotationsAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import de.is24.deadcode4j.AnalysisSink; 5 | import de.is24.deadcode4j.AnalyzedCode; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.util.Set; 9 | 10 | import static com.google.common.collect.Sets.newHashSet; 11 | 12 | /** 13 | * Analyzes class files: marks a class as being in use if it is annotated with one of the specified annotations. 14 | * 15 | * @since 1.3 16 | */ 17 | public final class CustomAnnotationsAnalyzer extends AnnotationsAnalyzer { 18 | 19 | @Nonnull 20 | private final Set annotationsNotFoundInClassPath; 21 | 22 | /** 23 | * Creates a new CustomAnnotationsAnalyzer. 24 | * 25 | * @param customAnnotations a list of fully qualified (annotation) class names indicating a class is still in use 26 | * @since 1.3 27 | */ 28 | public CustomAnnotationsAnalyzer(@Nonnull Iterable customAnnotations) { 29 | super("_custom-annotations_", customAnnotations); 30 | annotationsNotFoundInClassPath = newHashSet(customAnnotations); 31 | } 32 | 33 | @Override 34 | public void finishAnalysis(@Nonnull AnalysisContext analysisContext) { 35 | super.finishAnalysis(analysisContext); 36 | annotationsNotFoundInClassPath.removeAll(getAnnotationsFoundInClassPath(analysisContext)); 37 | } 38 | 39 | @Override 40 | public void finishAnalysis(@Nonnull AnalysisSink analysisSink, @Nonnull AnalyzedCode analyzedCode) { 41 | super.finishAnalysis(analysisSink, analyzedCode); 42 | for (String interfaceName : annotationsNotFoundInClassPath) { 43 | logger.warn("Annotation [{}] wasn't ever found in the class path. You should remove the configuration entry.", interfaceName); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/CustomInterfacesAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import de.is24.deadcode4j.AnalysisSink; 5 | import de.is24.deadcode4j.AnalyzedCode; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.util.Set; 9 | 10 | import static com.google.common.collect.Sets.newHashSet; 11 | 12 | /** 13 | * Analyzes class files: marks a class as being in use if it explicitly implements one of the specified interfaces. 14 | * 15 | * @since 1.4 16 | */ 17 | public final class CustomInterfacesAnalyzer extends InterfacesAnalyzer { 18 | 19 | @Nonnull 20 | private final Set interfacesNotFoundInClassPath; 21 | 22 | /** 23 | * Creates a new CustomInterfacesAnalyzer. 24 | * 25 | * @param customInterfaces a list of fully qualified interface names indicating that the implementing class is in use 26 | * @since 1.4 27 | */ 28 | public CustomInterfacesAnalyzer(@Nonnull Iterable customInterfaces) { 29 | super("_custom-interfaces_", customInterfaces); 30 | interfacesNotFoundInClassPath = newHashSet(customInterfaces); 31 | } 32 | 33 | @Override 34 | public void finishAnalysis(@Nonnull AnalysisContext analysisContext) { 35 | super.finishAnalysis(analysisContext); 36 | interfacesNotFoundInClassPath.removeAll(getInterfacesFoundInClassPath(analysisContext)); 37 | } 38 | 39 | @Override 40 | public void finishAnalysis(@Nonnull AnalysisSink analysisSink, @Nonnull AnalyzedCode analyzedCode) { 41 | super.finishAnalysis(analysisSink, analyzedCode); 42 | for (String interfaceName : interfacesNotFoundInClassPath) { 43 | logger.warn("Interface [{}] wasn't ever found in the class path. You should remove the configuration entry.", interfaceName); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/CustomSuperClassAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import de.is24.deadcode4j.AnalysisSink; 5 | import de.is24.deadcode4j.AnalyzedCode; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.util.Set; 9 | 10 | import static com.google.common.collect.Sets.newHashSet; 11 | 12 | /** 13 | * Analyzes class files: marks a class as being in use if it is a direct subclass of one of the specified classes. 14 | * 15 | * @since 1.4 16 | */ 17 | public final class CustomSuperClassAnalyzer extends SuperClassAnalyzer { 18 | 19 | @Nonnull 20 | private final Set superClassesNotFoundInClassPath; 21 | 22 | /** 23 | * Creates a new CustomAnnotationsAnalyzer. 24 | * 25 | * @param customSuperClasses a list of fully qualified class names indicating that the extending class is in use 26 | * @since 1.4 27 | */ 28 | public CustomSuperClassAnalyzer(@Nonnull Iterable customSuperClasses) { 29 | super("_custom-superclass_", customSuperClasses); 30 | superClassesNotFoundInClassPath = newHashSet(customSuperClasses); 31 | } 32 | 33 | @Override 34 | public void finishAnalysis(@Nonnull AnalysisContext analysisContext) { 35 | super.finishAnalysis(analysisContext); 36 | superClassesNotFoundInClassPath.removeAll(getSuperClassesFoundInClassPath(analysisContext)); 37 | } 38 | 39 | @Override 40 | public void finishAnalysis(@Nonnull AnalysisSink analysisSink, @Nonnull AnalyzedCode analyzedCode) { 41 | super.finishAnalysis(analysisSink, analyzedCode); 42 | for (String interfaceName : superClassesNotFoundInClassPath) { 43 | logger.warn("SuperClass [{}] wasn't ever found in the class path. You should remove the configuration entry.", interfaceName); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/JeeAnnotationsAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes class files: marks a class as being in use if it is annotated with one of those JEE annotations: 5 | *
    6 | *
  • javax.annotation.ManagedBean
  • 7 | *
  • javax.faces.component.behavior.FacesBehavior
  • 8 | *
  • javax.faces.convert.FacesConverter
  • 9 | *
  • javax.faces.event.ListenerFor
  • 10 | *
  • javax.faces.event.ListenersFor
  • 11 | *
  • javax.faces.event.NamedEvent
  • 12 | *
  • javax.faces.render.FacesBehaviorRenderer
  • 13 | *
  • javax.faces.render.FacesRenderer
  • 14 | *
  • javax.faces.validator.FacesValidator
  • 15 | *
  • javax.faces.view.facelets.FaceletsResourceResolver
  • 16 | *
  • javax.inject.Named
  • 17 | *
  • javax.persistence.metamodel.StaticMetamodel
  • 18 | *
  • javax.xml.bind.annotation.XmlRegistry
  • 19 | *
  • javax.xml.bind.annotation.XmlSchema
  • 20 | *
21 | * 22 | * @since 1.3 23 | */ 24 | public final class JeeAnnotationsAnalyzer extends AnnotationsAnalyzer { 25 | 26 | public JeeAnnotationsAnalyzer() { 27 | super("_JEE-Annotation_", 28 | "javax.annotation.ManagedBean", 29 | "javax.faces.component.behavior.FacesBehavior", 30 | "javax.faces.convert.FacesConverter", 31 | "javax.faces.event.ListenerFor", 32 | "javax.faces.event.ListenersFor", 33 | "javax.faces.event.NamedEvent", 34 | "javax.faces.render.FacesBehaviorRenderer", 35 | "javax.faces.render.FacesRenderer", 36 | "javax.faces.validator.FacesValidator", 37 | "javax.faces.view.facelets.FaceletsResourceResolver", 38 | "javax.inject.Named", 39 | "javax.persistence.metamodel.StaticMetamodel", 40 | "javax.xml.bind.annotation.XmlRegistry", 41 | "javax.xml.bind.annotation.XmlSchema"); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/JerseyWebXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | 4 | import de.is24.deadcode4j.AnalysisContext; 5 | import de.is24.deadcode4j.analyzer.webxml.BaseWebXmlAnalyzer; 6 | import de.is24.deadcode4j.analyzer.webxml.Param; 7 | import de.is24.deadcode4j.analyzer.webxml.WebXmlHandler; 8 | 9 | import javax.annotation.Nonnull; 10 | import java.util.List; 11 | 12 | /** 13 | * Analyzes web.xml files: looks for servlet parameters that define the JAX-RS applications. 14 | * 15 | *

A user can extend the Jersey Application class. In order to use this application the user must set the init-param 16 | * "javax.ws.rs.Application" of a servlet or a filter. (We don't check the servlet or filter class because there are 17 | * several classes of this kind. See Jersey documentation 18 | * 4.7.1.1. Custom 19 | * Application subclass 20 | * 21 | * @since 2.1.0 22 | */ 23 | public class JerseyWebXmlAnalyzer extends BaseWebXmlAnalyzer { 24 | @Nonnull 25 | @Override 26 | protected WebXmlHandler createWebXmlHandlerFor(@Nonnull final AnalysisContext analysisContext) { 27 | return new WebXmlHandler() { 28 | @Override 29 | public void filter(String className, List initParams) { 30 | //We don't check the filter class because there are several classes of this kind. 31 | scanParams(initParams); 32 | } 33 | 34 | @Override 35 | public void servlet(String className, List initParams) { 36 | //We don't check the servlet class because there are several classes of this kind. 37 | scanParams(initParams); 38 | } 39 | 40 | private void scanParams(List initParams) { 41 | for (Param initParam: initParams) { 42 | if (initParam.getName().equals("javax.ws.rs.Application")) { 43 | analysisContext.addDependencies("_Jersey_", initParam.getValue()); 44 | } 45 | } 46 | } 47 | }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/JettyXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes Jetty XML configuration files. 5 | * Reports the {@code class} and {@code type} attributes as classes being referenced. 6 | * 7 | * @since 2.0.0 8 | */ 9 | public class JettyXmlAnalyzer extends SimpleXmlAnalyzer { 10 | 11 | public JettyXmlAnalyzer() { 12 | super("_Jetty-XML_", ".xml", "Configure"); 13 | registerClassAttribute("Arg", "type"); 14 | registerClassAttribute("Array", "type"); 15 | registerClassAttribute("Call", "class"); 16 | registerClassAttribute("Configure", "class"); 17 | registerClassAttribute("Get", "class"); 18 | registerClassAttribute("Item", "type"); 19 | registerClassAttribute("New", "class"); 20 | registerClassAttribute("Put", "type"); 21 | registerClassAttribute("Set", "class"); 22 | registerClassAttribute("Set", "type"); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/LogbackXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | *

Analyzes Logback XML configuration files (only files named logback.xml) by reporting every 5 | * class and actionClass attribute as being live code.

6 | * To understand why this wildcard approach is chosen, have a look at section 7 | * Configuration file syntax and 8 | * Joran of the Logback documentation. 9 | * 10 | * @since 2.2.0 11 | */ 12 | public class LogbackXmlAnalyzer extends ExtendedXmlAnalyzer { 13 | 14 | public LogbackXmlAnalyzer() { 15 | super("_Logback-XML_", "logback.xml", "configuration"); 16 | anyElement().registerAttributeAsClass("actionClass"); 17 | anyElement().registerAttributeAsClass("class"); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/MainClassAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import javassist.CtClass; 5 | import javassist.Modifier; 6 | import javassist.bytecode.AccessFlag; 7 | import javassist.bytecode.MethodInfo; 8 | 9 | import javax.annotation.Nonnull; 10 | 11 | import static com.google.common.collect.Iterables.filter; 12 | 13 | /** 14 | * Analyzes class files: marks a class as being in use if it defines a main method. 15 | * 16 | * @since 2.0.0 17 | */ 18 | public class MainClassAnalyzer extends ByteCodeAnalyzer { 19 | 20 | private static boolean isPublicStatic(MethodInfo methodInfo) { 21 | int modifier = AccessFlag.toModifier(methodInfo.getAccessFlags()); 22 | return Modifier.isPublic(modifier) && Modifier.isStatic(modifier); 23 | } 24 | 25 | private static boolean matchesSignature(MethodInfo methodInfo) { 26 | return "([Ljava/lang/String;)V".equals(methodInfo.getDescriptor()); 27 | } 28 | 29 | @Override 30 | protected void analyzeClass(@Nonnull AnalysisContext analysisContext, @Nonnull CtClass clazz) { 31 | String clazzName = clazz.getName(); 32 | analysisContext.addAnalyzedClass(clazzName); 33 | 34 | for (MethodInfo methodInfo : filter(clazz.getClassFile2().getMethods(), MethodInfo.class)) { 35 | if (methodInfo.isMethod() 36 | && isPublicStatic(methodInfo) 37 | && "main".equals(methodInfo.getName()) 38 | && matchesSignature(methodInfo)) { 39 | analysisContext.addDependencies("_Main-Class_", clazz.getName()); 40 | } 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/SpringAnnotationsAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes class files: marks a class as being in use if it is annotated with one of those Spring annotations: 5 | *
    6 | *
  • org.springframework.jmx.export.annotation.ManagedResource
  • 7 | *
  • org.springframework.stereotype.Component
  • 8 | *
9 | *

10 | * Those Spring annotations are marked with @Component and thus are recursively considered as well: 11 | *

    12 | *
  • org.springframework.context.annotation.Configuration
  • 13 | *
  • org.springframework.stereotype.Controller
  • 14 | *
  • org.springframework.stereotype.Service
  • 15 | *
  • org.springframework.stereotype.Repository
  • 16 | *
17 | * 18 | * @since 1.3 19 | */ 20 | public final class SpringAnnotationsAnalyzer extends AnnotationsAnalyzer { 21 | 22 | public SpringAnnotationsAnalyzer() { 23 | super("_Spring-Annotation_", 24 | "org.springframework.jmx.export.annotation.ManagedResource", 25 | "org.springframework.stereotype.Component"); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/SpringNamespaceHandlerAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import org.apache.commons.io.IOUtils; 5 | 6 | import javax.annotation.Nonnull; 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.IOException; 10 | import java.util.Properties; 11 | 12 | import static com.google.common.collect.Iterables.filter; 13 | 14 | /** 15 | * Analyzes 16 | * spring.handlers property files and lists the defined namespace handlers as classes being 17 | * referenced. 18 | */ 19 | public class SpringNamespaceHandlerAnalyzer extends AnalyzerAdapter { 20 | 21 | @Override 22 | public void doAnalysis(@Nonnull AnalysisContext analysisContext, @Nonnull File file) { 23 | if (file.getAbsolutePath().endsWith("META-INF/spring.handlers")) { 24 | logger.debug("Analyzing property file [{}]...", file); 25 | registerSpringHandlersDefinedIn(analysisContext, file); 26 | } 27 | } 28 | 29 | private void registerSpringHandlersDefinedIn(AnalysisContext analysisContext, File file) { 30 | Properties springNamespaceHandlers = readPropertyFile(file); 31 | analysisContext.addDependencies("_Spring-NamespaceHandler_", filter(springNamespaceHandlers.values(), String.class)); 32 | } 33 | 34 | private Properties readPropertyFile(File file) { 35 | Properties properties = new Properties(); 36 | FileInputStream in = null; 37 | try { 38 | in = new FileInputStream(file); 39 | properties.load(in); 40 | } catch (IOException e) { 41 | throw new RuntimeException("Failed to read [" + file + "]!", e); 42 | } finally { 43 | IOUtils.closeQuietly(in); 44 | } 45 | return properties; 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/SpringWebApplicationInitializerAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes both web.xml and class files: looks for implementations of 5 | * {@link org.springframework.web.WebApplicationInitializer} if the metadata-complete attribute of the 6 | * web-app element is missing or set to "false". 7 | * 8 | * @since 1.5 9 | */ 10 | public class SpringWebApplicationInitializerAnalyzer extends ServletContainerInitializerAnalyzer { 11 | 12 | public SpringWebApplicationInitializerAnalyzer() { 13 | super("_Spring-WebApplicationInitializer_", "org.springframework.web.WebApplicationInitializer"); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/SpringWebFlowAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes Spring Web Flow XML 5 | * files: lists 6 | *
    7 | *
  • a var's class
  • 8 | *
  • an attribute's/input's/output's/set's type
  • 9 | *
  • the result-type of an evaluate
  • 10 | *
11 | * as classes being referenced. 12 | * 13 | * @since 1.5 14 | */ 15 | public final class SpringWebFlowAnalyzer extends SimpleXmlAnalyzer { 16 | 17 | public SpringWebFlowAnalyzer() { 18 | super("_SpringWebFlow-XML_", ".xml", "flow"); 19 | registerClassAttribute("attribute", "type"); 20 | registerClassAttribute("evaluate", "result-type"); 21 | registerClassAttribute("input", "type"); 22 | registerClassAttribute("output", "type"); 23 | registerClassAttribute("set", "type"); 24 | registerClassAttribute("var", "class"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/TldAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes *.tld files: lists the function, listener, tag, tag extra info & validator classes being 5 | * referenced. 6 | * 7 | * @since 1.2.0 8 | */ 9 | public final class TldAnalyzer extends SimpleXmlAnalyzer { 10 | 11 | public TldAnalyzer() { 12 | super("_tld_", ".tld", "taglib"); 13 | registerClassElement("function-class"); 14 | registerClassElement("listener-class"); 15 | registerClassElement("tag-class"); 16 | registerClassElement("tei-class"); 17 | registerClassElement("validator-class"); 18 | // this was valid at least for J2EE 1.2, see http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd 19 | registerClassElement("tagclass"); 20 | registerClassElement("teiclass"); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/WebXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import de.is24.deadcode4j.analyzer.webxml.BaseWebXmlAnalyzer; 5 | import de.is24.deadcode4j.analyzer.webxml.Param; 6 | import de.is24.deadcode4j.analyzer.webxml.WebXmlHandler; 7 | 8 | import javax.annotation.Nonnull; 9 | import java.util.List; 10 | 11 | /** 12 | * Analyzes web.xml files: lists the listener, filter & servlet classes being referenced. 13 | * 14 | * @since 1.2.0 15 | */ 16 | public final class WebXmlAnalyzer extends BaseWebXmlAnalyzer { 17 | 18 | @Nonnull 19 | @Override 20 | protected WebXmlHandler createWebXmlHandlerFor(@Nonnull final AnalysisContext analysisContext) { 21 | return new WebXmlHandler() { 22 | @Override 23 | public void filter(String className, List initParams) { 24 | addDependency(className); 25 | } 26 | 27 | @Override 28 | public void listener(String className) { 29 | addDependency(className); 30 | } 31 | 32 | @Override 33 | public void servlet(String className, List initParams) { 34 | addDependency(className); 35 | } 36 | 37 | private void addDependency(String className) { 38 | analysisContext.addDependencies("_web.xml_", className); 39 | } 40 | }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/WsddAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | /** 4 | * Analyzes .wsdd 5 | * files: lists the defined Axis Service classes being referenced. 6 | * 7 | * @since 1.5 8 | */ 9 | public final class WsddAnalyzer extends SimpleXmlAnalyzer { 10 | 11 | public WsddAnalyzer() { 12 | super("_Axis-WSSD_", ".wsdd", "deployment"); 13 | registerClassAttribute("parameter", "value").withAttributeValue("name", "className"); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/javassist/ClassPathFilter.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.javassist; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import de.is24.guava.NonNullFunction; 5 | import javassist.ClassPool; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import javax.annotation.Nonnull; 10 | import java.util.Set; 11 | 12 | import static com.google.common.collect.Sets.newHashSet; 13 | import static de.is24.deadcode4j.analyzer.javassist.ClassPoolAccessor.classPoolAccessorFor; 14 | 15 | /** 16 | * This function returns a set containing only those classes that exist within the class path of the specified context. 17 | * It is intended to be used in conjunction with 18 | * {@link de.is24.deadcode4j.AnalysisContext#getOrCreateCacheEntry(Object, de.is24.guava.NonNullFunction)}. 19 | * 20 | * @since 2.0.0 21 | */ 22 | public class ClassPathFilter implements NonNullFunction> { 23 | @Nonnull 24 | private final Logger logger = LoggerFactory.getLogger(getClass()); 25 | @Nonnull 26 | private final Set classes; 27 | 28 | /** 29 | * Creates a new ClassPathFilter for the given class names. 30 | * 31 | * @since 2.0.0 32 | */ 33 | public ClassPathFilter(@Nonnull Set classes) { 34 | this.classes = classes; 35 | } 36 | 37 | @Nonnull 38 | @Override 39 | public Set apply(@Nonnull AnalysisContext input) { 40 | ClassPool classPool = classPoolAccessorFor(input).getClassPool(); 41 | Set knownClasses = newHashSet(); 42 | for (String className : this.classes) { 43 | if (classPool.find(className) != null) { 44 | knownClasses.add(className); 45 | } 46 | } 47 | logger.debug("Found those classes in the class path: {}", knownClasses); 48 | return knownClasses; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/webxml/Param.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.webxml; 2 | 3 | /** 4 | * Representation of a {@code context-param} or {@code init-param} node. 5 | * {@code Param} is a value-based class. 6 | * 7 | * @since 2.1.0 8 | */ 9 | public class Param { 10 | private final String name; 11 | private final String value; 12 | 13 | /** 14 | * Creates a new {@code Param} object. 15 | * @param name the text of the {@code param-name} node. 16 | * @param value the text of the {@code param-value} node. 17 | */ 18 | public Param(String name, String value) { 19 | this.name = name; 20 | this.value = value; 21 | } 22 | 23 | /** 24 | * Returns the text of the {@code param-name} node. 25 | */ 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | /** 31 | * Returns the text of the {@code param-value} node. 32 | */ 33 | public String getValue() { 34 | return value; 35 | } 36 | 37 | @Override 38 | public boolean equals(Object o) { 39 | if (this == o) { 40 | return true; 41 | } 42 | if (!getClass().isInstance(o)) { 43 | return false; 44 | } 45 | 46 | Param param = (Param) o; 47 | 48 | if (name != null ? !name.equals(param.name) : param.name != null) { 49 | return false; 50 | } 51 | return !(value != null ? !value.equals(param.value) : param.value != null); 52 | 53 | } 54 | 55 | @Override 56 | public int hashCode() { 57 | int result = name != null ? name.hashCode() : 0; 58 | result = 31 * result + (value != null ? value.hashCode() : 0); 59 | return result; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return "Param{" + 65 | "name='" + name + '\'' + 66 | ", value='" + value + '\'' + 67 | '}'; 68 | } 69 | } -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/analyzer/webxml/WebXmlHandler.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.webxml; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Base class for web.xml event handlers. {@code WebXmlHandler}s are used by 7 | * {@link BaseWebXmlAnalyzer} that translates general XML events into web.xml 8 | * events. 9 | * 10 | * @since 2.1.0 11 | */ 12 | public abstract class WebXmlHandler { 13 | /** 14 | * Receive notification about a {@code context-param} node. 15 | * 16 | * @param param the param. 17 | */ 18 | public void contextParam(Param param) { 19 | } 20 | 21 | /** 22 | * Receive notification about a {@code filter} node. 23 | * 24 | * @param className the text of the {@code filter-class} node. 25 | * @param initParams the filters init params. 26 | */ 27 | public void filter(String className, List initParams) { 28 | } 29 | 30 | /** 31 | * Receive notification about a {@code listener} node. 32 | * 33 | * @param className the text of the {@code listener-class} node. 34 | */ 35 | public void listener(String className) { 36 | } 37 | 38 | /** 39 | * Receive notification about a {@code servlet} node. 40 | * 41 | * @param className the text of the {@code servlet-class} node. 42 | * @param initParams the servlets init params. 43 | */ 44 | public void servlet(String className, List initParams) { 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/plugin/CustomXml.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.plugin; 2 | 3 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 4 | 5 | import java.util.List; 6 | 7 | import static com.google.common.collect.Lists.newArrayList; 8 | 9 | /** 10 | * CustomXml is used to configure a {@link de.is24.deadcode4j.analyzer.CustomXmlAnalyzer}. 11 | * 12 | * @since 1.3 13 | */ 14 | public class CustomXml { 15 | 16 | @java.lang.SuppressWarnings("UnusedDeclaration") 17 | @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Set by Plexus when configuring the plugin") 18 | private String endOfFileName; 19 | @java.lang.SuppressWarnings("UnusedDeclaration") 20 | @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Set by Plexus when configuring the plugin") 21 | private String rootElement; 22 | private final List xPaths = newArrayList(); 23 | 24 | public String getEndOfFileName() { 25 | return endOfFileName; 26 | } 27 | 28 | public String getRootElement() { 29 | return rootElement; 30 | } 31 | 32 | public List getXPaths() { 33 | return xPaths; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/plugin/FindDeadCodeMojo.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.plugin; 2 | 3 | import org.apache.maven.plugins.annotations.Execute; 4 | import org.apache.maven.plugins.annotations.Mojo; 5 | 6 | import static org.apache.maven.plugins.annotations.LifecyclePhase.PACKAGE; 7 | import static org.apache.maven.plugins.annotations.ResolutionScope.COMPILE; 8 | 9 | /** 10 | * Finds dead (i.e. unused) code. Causes the 11 | * package phase to be 12 | * executed. 13 | * 14 | * @see FindDeadCodeOnlyMojo 15 | * @since 1.0.0 16 | */ 17 | @Mojo(name = "find", 18 | aggregator = true, 19 | requiresProject = true, 20 | requiresDependencyCollection = COMPILE, 21 | threadSafe = true) 22 | @Execute(phase = PACKAGE) 23 | public class FindDeadCodeMojo extends FindDeadCodeOnlyMojo { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/plugin/SubDirectoryFilter.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.plugin; 2 | 3 | import javax.annotation.Nonnull; 4 | import java.io.File; 5 | import java.io.FileFilter; 6 | 7 | /** 8 | * A SubDirectoryFilter only accepts a specific subdirectory of a directory. 9 | * 10 | * @since 1.2.0 11 | */ 12 | public class SubDirectoryFilter implements FileFilter { 13 | 14 | private final File directory; 15 | private final String subDirectoryName; 16 | 17 | public SubDirectoryFilter(@Nonnull File directory, @Nonnull String subDirectoryName) { 18 | this.directory = directory; 19 | this.subDirectoryName = subDirectoryName; 20 | } 21 | 22 | @Override 23 | public boolean accept(File file) { 24 | return file.isDirectory() && directory.equals(file.getParentFile()) && subDirectoryName.equals(file.getName()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/plugin/packaginghandler/DefaultPackagingHandler.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.plugin.packaginghandler; 2 | 3 | import de.is24.deadcode4j.Repository; 4 | import org.apache.maven.plugin.MojoExecutionException; 5 | import org.apache.maven.project.MavenProject; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.Nullable; 9 | import java.io.File; 10 | 11 | import static de.is24.deadcode4j.Utils.getKeyFor; 12 | 13 | /** 14 | * The DefaultPackagingHandler returns the default output directory if it exists. 15 | * 16 | * @since 1.2.0 17 | */ 18 | public class DefaultPackagingHandler extends PackagingHandler { 19 | 20 | @Nullable 21 | @Override 22 | public Repository getOutputRepositoryFor(@Nonnull MavenProject project) throws MojoExecutionException { 23 | logger.debug("Project {} has {} packaging, looking for output directory...", getKeyFor(project), project.getPackaging()); 24 | File outputDirectory = new File(project.getBuild().getOutputDirectory()); 25 | if (!outputDirectory.exists()) { 26 | logger.warn("The output directory of " + getKeyFor(project) + 27 | " does not exist - assuming the project simply has nothing to provide!"); 28 | return null; 29 | } 30 | logger.debug(" Found output directory [{}].", outputDirectory); 31 | return new Repository(outputDirectory); 32 | } 33 | 34 | @Nonnull 35 | @Override 36 | public Iterable getAdditionalRepositoriesFor(@Nonnull MavenProject project) throws MojoExecutionException { 37 | return getJavaFilesOfCompileSourceRootsAsRepositories(project); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/de/is24/deadcode4j/plugin/packaginghandler/PomPackagingHandler.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.plugin.packaginghandler; 2 | 3 | import de.is24.deadcode4j.Repository; 4 | import org.apache.maven.plugin.MojoExecutionException; 5 | import org.apache.maven.project.MavenProject; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.Nullable; 9 | 10 | import static de.is24.deadcode4j.Utils.getKeyFor; 11 | 12 | /** 13 | * The PomPackagingHandler returns no repository, as there's nothing to analyze. 14 | * 15 | * @since 1.2.0 16 | */ 17 | public class PomPackagingHandler extends PackagingHandler { 18 | 19 | @Nullable 20 | @Override 21 | public Repository getOutputRepositoryFor(@Nonnull MavenProject project) throws MojoExecutionException { 22 | logger.debug("Project {} has pom packaging, so it is skipped.", getKeyFor(project)); 23 | return null; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/is24/guava/NonNullFunction.java: -------------------------------------------------------------------------------- 1 | package de.is24.guava; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | /** 6 | * A NonNullFunction basically is a {@link com.google.common.base.Function} that 7 | * neither accepts null nor is it allowed to return null. 8 | * 9 | * @since 2.0.0 10 | */ 11 | public interface NonNullFunction { 12 | 13 | /** 14 | * Returns the result of applying this function to the given input. 15 | * 16 | * @since 2.0.0 17 | */ 18 | @Nonnull 19 | T apply(@Nonnull F input); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/de/is24/guava/NonNullFunctions.java: -------------------------------------------------------------------------------- 1 | package de.is24.guava; 2 | 3 | import com.google.common.base.Function; 4 | import com.google.common.base.Optional; 5 | import de.is24.deadcode4j.Utils; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.Nullable; 9 | 10 | /** 11 | * Provides convenience methods for {@link de.is24.guava.NonNullFunction}. 12 | * 13 | * @since 2.0.0 14 | */ 15 | public final class NonNullFunctions { 16 | 17 | private NonNullFunctions() {} 18 | 19 | /** 20 | * Returns a NonNullFunction that will call the specified functions one by one until a return value is 21 | * present or the end of the call chain is reached. 22 | * 23 | * @since 2.0.0 24 | */ 25 | @Nonnull 26 | public static NonNullFunction> or(@Nonnull final NonNullFunction>... functions) { 27 | return new NonNullFunction>() { 28 | @Nonnull 29 | @Override 30 | public Optional apply(@Nonnull F input) { 31 | for (int i = 0; ; ) { 32 | Optional result = functions[i++].apply(input); 33 | if (result.isPresent() || i == functions.length) { 34 | return result; 35 | } 36 | } 37 | } 38 | }; 39 | } 40 | 41 | /** 42 | * Transforms a NonNullFunction into a Function. 43 | * If a Function's input is null, a NullPointerException is thrown. 44 | * 45 | * @since 2.0.0 46 | */ 47 | @Nonnull 48 | public static Function toFunction(@Nonnull final NonNullFunction nonNullFunction) { 49 | return new Function() { 50 | @Nullable 51 | @Override 52 | @SuppressWarnings("ConstantConditions") 53 | public T apply(@Nullable F input) { 54 | return nonNullFunction.apply(Utils.checkNotNull(input)); 55 | } 56 | }; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/de/is24/javaparser/ImportDeclarations.java: -------------------------------------------------------------------------------- 1 | package de.is24.javaparser; 2 | 3 | import com.google.common.base.Predicate; 4 | import com.github.javaparser.ast.ImportDeclaration; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.Nullable; 8 | 9 | import static de.is24.deadcode4j.Utils.checkNotNull; 10 | 11 | /** 12 | * Provides convenience methods for dealing with {@link ImportDeclaration}s. 13 | * 14 | * @since 2.0.0 15 | */ 16 | public final class ImportDeclarations { 17 | 18 | private ImportDeclarations() {} 19 | 20 | /** 21 | * Returns a Predicate that evaluates to true if the ImportDeclaration being 22 | * tested is an asterisk import. 23 | * 24 | * @since 2.0.0 25 | */ 26 | @Nonnull 27 | public static Predicate isAsterisk() { 28 | return new Predicate() { 29 | @Override 30 | @SuppressWarnings("ConstantConditions") 31 | public boolean apply(@Nullable ImportDeclaration input) { 32 | return checkNotNull(input).isAsterisk(); 33 | } 34 | }; 35 | } 36 | 37 | /** 38 | * Returns a Predicate that evaluates to true if the ImportDeclaration being 39 | * tested is a static import. 40 | * 41 | * @since 2.0.0 42 | */ 43 | @Nonnull 44 | public static Predicate isStatic() { 45 | return new Predicate() { 46 | @Override 47 | @SuppressWarnings("ConstantConditions") 48 | public boolean apply(@Nullable ImportDeclaration input) { 49 | return checkNotNull(input).isStatic(); 50 | } 51 | }; 52 | } 53 | 54 | /** 55 | * Returns a Predicate that evaluates to true if the last qualifier of the 56 | * ImportDeclaration being tested matches the given String. 57 | * 58 | * @since 2.0.0 59 | */ 60 | @Nonnull 61 | public static Predicate refersTo(@Nonnull final String lastQualifier) { 62 | return new Predicate() { 63 | @Override 64 | @SuppressWarnings("ConstantConditions") 65 | public boolean apply(@Nullable ImportDeclaration input) { 66 | return lastQualifier.equals(checkNotNull(input).getName().getName()); 67 | } 68 | }; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/de/is24/maven/slf4j/AbstractSlf4jMojo.java: -------------------------------------------------------------------------------- 1 | package de.is24.maven.slf4j; 2 | 3 | import org.apache.maven.plugin.AbstractMojo; 4 | import org.apache.maven.plugin.MojoExecutionException; 5 | import org.apache.maven.plugin.MojoFailureException; 6 | import org.slf4j.impl.StaticLoggerBinder; 7 | 8 | /** 9 | * A subclass of AbstractMojo that makes sure the {@link MavenPluginLoggerFactory} is set up and torn down. 10 | * 11 | * @author Sebastian Kirsch 12 | * @since 1.5 13 | */ 14 | public abstract class AbstractSlf4jMojo extends AbstractMojo { 15 | @Override 16 | public final void execute() throws MojoExecutionException, MojoFailureException { 17 | StaticLoggerBinder staticLoggerBinder = StaticLoggerBinder.getSingleton(); 18 | staticLoggerBinder.setLog(getLog()); 19 | try { 20 | doExecute(); 21 | } finally { 22 | staticLoggerBinder.revokeLog(); 23 | } 24 | } 25 | 26 | /** 27 | * Subclasses need to implement this method instead of {@link org.apache.maven.plugin.Mojo#execute()}. 28 | * 29 | * @since 1.5 30 | */ 31 | protected abstract void doExecute() throws MojoExecutionException, MojoFailureException; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/de/is24/maven/slf4j/MavenPluginLoggerFactory.java: -------------------------------------------------------------------------------- 1 | package de.is24.maven.slf4j; 2 | 3 | import org.apache.maven.plugin.logging.Log; 4 | import org.slf4j.ILoggerFactory; 5 | import org.slf4j.Logger; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.Nullable; 9 | 10 | /** 11 | * An ILoggerFactory creating instances of {@link LoggerForMavenLog}. 12 | * 13 | * @author Sebastian Kirsch 14 | * @since 1.5 15 | */ 16 | public class MavenPluginLoggerFactory implements ILoggerFactory { 17 | private final Log log; 18 | 19 | public MavenPluginLoggerFactory(@Nonnull Log log) { 20 | this.log = log; 21 | } 22 | 23 | @Override 24 | public Logger getLogger(@Nullable String name) { 25 | return new LoggerForMavenLog(log, name); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/A.java: -------------------------------------------------------------------------------- 1 | public class A { 2 | private B b; 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/AnnotatedClass.java: -------------------------------------------------------------------------------- 1 | import de.is24.deadcode4j.junit.Annotation; 2 | 3 | @Annotation 4 | public class AnnotatedClass { 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/B.java: -------------------------------------------------------------------------------- 1 | public class B { 2 | private A a; 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/ClassAnnotatedWithAnnotatedAnnotation.java: -------------------------------------------------------------------------------- 1 | import de.is24.deadcode4j.junit.AnnotatedAnnotation; 2 | 3 | @AnnotatedAnnotation 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassAnnotatedWithAnnotatedAnnotation { 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/ClassImplementingCloneable.java: -------------------------------------------------------------------------------- 1 | @SuppressWarnings("UnusedDeclaration") 2 | public class ClassImplementingCloneable implements Cloneable { 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/ClassImplementingExternalizable.java: -------------------------------------------------------------------------------- 1 | import java.io.Externalizable; 2 | import java.io.ObjectInput; 3 | import java.io.ObjectOutput; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class ClassImplementingExternalizable implements Externalizable { 7 | @Override 8 | public void writeExternal(ObjectOutput out) { 9 | } 10 | 11 | @Override 12 | public void readExternal(ObjectInput in) { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/ClassWithInnerClass.java: -------------------------------------------------------------------------------- 1 | @SuppressWarnings("unused") 2 | public class ClassWithInnerClass { 3 | public static class InnerClass { } 4 | } -------------------------------------------------------------------------------- /src/test/java/ClassWithTypeArgument.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassWithTypeArgument { 4 | public ClassWithTypeArgument() { new ArrayList(); } 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/CustomNamespaceHandler.java: -------------------------------------------------------------------------------- 1 | public class CustomNamespaceHandler { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/DeadServlet.java: -------------------------------------------------------------------------------- 1 | import javax.servlet.http.HttpServlet; 2 | import java.io.Serializable; 3 | 4 | @Deprecated 5 | public class DeadServlet extends HttpServlet implements Serializable { 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/DependingClass.java: -------------------------------------------------------------------------------- 1 | public class DependingClass { 2 | private IndependentClass b; 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/IndependentClass.java: -------------------------------------------------------------------------------- 1 | public class IndependentClass { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/MainClass.java: -------------------------------------------------------------------------------- 1 | public class MainClass { 2 | public static void main(String[] args) { } 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/SingleClass.java: -------------------------------------------------------------------------------- 1 | public class SingleClass { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/SomeServletInitializer.java: -------------------------------------------------------------------------------- 1 | import de.is24.deadcode4j.junit.SomeInterface; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class SomeServletInitializer implements SomeInterface { } 4 | -------------------------------------------------------------------------------- /src/test/java/SpringXmlBean.java: -------------------------------------------------------------------------------- 1 | public class SpringXmlBean { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/SubClassOfAnnotatedClass.java: -------------------------------------------------------------------------------- 1 | @SuppressWarnings("UnusedDeclaration") 2 | public class SubClassOfAnnotatedClass extends AnnotatedClass { 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/SubClassOfClassImplementingExternalizable.java: -------------------------------------------------------------------------------- 1 | @SuppressWarnings("UnusedDeclaration") 2 | public class SubClassOfClassImplementingExternalizable extends ClassImplementingExternalizable { 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/SubClassOfSubClassThatShouldBeLive.java: -------------------------------------------------------------------------------- 1 | @SuppressWarnings("UnusedDeclaration") 2 | public class SubClassOfSubClassThatShouldBeLive extends SubClassThatShouldBeLive { 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/SubClassThatShouldBeLive.java: -------------------------------------------------------------------------------- 1 | @SuppressWarnings("UnusedDeclaration") 2 | public class SubClassThatShouldBeLive extends Thread { 3 | } 4 | -------------------------------------------------------------------------------- /src/test/java/TagClass.java: -------------------------------------------------------------------------------- 1 | public class TagClass { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/TagExtraInfo.java: -------------------------------------------------------------------------------- 1 | public class TagExtraInfo { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/TagLibraryValidator.java: -------------------------------------------------------------------------------- 1 | public class TagLibraryValidator { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/TypeParameterClass.java: -------------------------------------------------------------------------------- 1 | @SuppressWarnings("UnusedDeclaration") 2 | public class TypeParameterClass { } 3 | -------------------------------------------------------------------------------- /src/test/java/WebAppFilter.java: -------------------------------------------------------------------------------- 1 | public class WebAppFilter { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/WebAppListener.java: -------------------------------------------------------------------------------- 1 | public class WebAppListener { 2 | } 3 | -------------------------------------------------------------------------------- /src/test/java/WebAppServlet.java: -------------------------------------------------------------------------------- 1 | import javax.servlet.http.HttpServlet; 2 | 3 | public class WebAppServlet extends HttpServlet { 4 | } 5 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/A_DeadCodeComputer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | import java.util.Collection; 7 | import java.util.EnumSet; 8 | import java.util.Map; 9 | import java.util.Set; 10 | 11 | import static com.google.common.collect.Maps.newHashMap; 12 | import static com.google.common.collect.Sets.newHashSet; 13 | import static org.hamcrest.MatcherAssert.assertThat; 14 | import static org.hamcrest.Matchers.contains; 15 | import static org.hamcrest.Matchers.hasSize; 16 | 17 | public class A_DeadCodeComputer { 18 | 19 | private DeadCodeComputer objectUnderTest; 20 | private Map> codeDependencies = newHashMap(); 21 | 22 | @Before 23 | public void setUpObjectUnderTest() { 24 | this.objectUnderTest = new DeadCodeComputer(); 25 | codeDependencies.clear(); 26 | } 27 | 28 | @Test 29 | public void recognizesASingleClassAsDeadCode() { 30 | setUpDependency("SingleClass"); 31 | 32 | Collection deadClasses = computeDeadClasses(); 33 | 34 | assertThat("Should recognize one class as dead", deadClasses, hasSize(1)); 35 | assertThat(deadClasses, contains("SingleClass")); 36 | } 37 | 38 | @Test 39 | public void recognizesTwoInterdependentClassesAsLiveCode() { 40 | setUpDependency("A", "B"); 41 | setUpDependency("B", "A"); 42 | 43 | Collection deadClasses = computeDeadClasses(); 44 | 45 | assertThat("Should find NO dead code", deadClasses, hasSize(0)); 46 | } 47 | 48 | @Test 49 | public void recognizesDependencyChainAsPartlyDeadCode() { 50 | setUpDependency("DependingClass", "IndependentClass"); 51 | setUpDependency("IndependentClass"); 52 | 53 | Collection deadClasses = computeDeadClasses(); 54 | 55 | assertThat("Should recognize one class as dead", deadClasses, contains("DependingClass")); 56 | } 57 | 58 | private void setUpDependency(String depender, String... dependees) { 59 | codeDependencies.put(depender, newHashSet(dependees)); 60 | } 61 | 62 | private Collection computeDeadClasses() { 63 | AnalyzedCode analyzedCode = new AnalyzedCode( 64 | EnumSet.noneOf(AnalysisStage.class), codeDependencies.keySet(), codeDependencies); 65 | DeadCode deadCode = objectUnderTest.computeDeadCode(analyzedCode); 66 | return deadCode.getDeadClasses(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/A_Module.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | import static de.is24.deadcode4j.ModuleBuilder.givenModule; 10 | import static java.util.Arrays.asList; 11 | import static org.hamcrest.MatcherAssert.assertThat; 12 | import static org.hamcrest.Matchers.contains; 13 | 14 | public final class A_Module { 15 | 16 | @Test 17 | public void sortsModulesByDependency() { 18 | Module c = givenModule("C"); 19 | Module b = givenModule("B", c); 20 | Module a = givenModule("A", b); 21 | 22 | Iterable modules = Module.sort(asList(b, a, c)); 23 | 24 | assertThat(modules, contains(c, b, a)); 25 | } 26 | 27 | @Test 28 | public void sortsUnrelatedModulesAlphabetically() { 29 | Module a = givenModule("A"); 30 | Module b = givenModule("B"); 31 | Module c = givenModule("C"); 32 | 33 | Iterable modules = Module.sort(asList(c, b, a)); 34 | 35 | assertThat(modules, contains(a, b, c)); 36 | } 37 | 38 | @Test 39 | public void sortsReallyComplexDependencyGraphCorrectly() { 40 | Module z = givenModule("Z"); 41 | Module y = givenModule("Y", z); 42 | Module c = givenModule("C", z); 43 | Module b = givenModule("B", c, y); 44 | Module a = givenModule("A", b); 45 | Module x = givenModule("X", c); 46 | 47 | List unsortedModules = asList(a, b, c, x, y, z); 48 | Collections.shuffle(unsortedModules); 49 | Iterable modules = Module.sort(unsortedModules); 50 | 51 | assertThat(modules, contains(z, c, y, b, x, a)); 52 | } 53 | 54 | @Test(expected = RuntimeException.class) 55 | public void throwsExceptionIfSortingFails() { 56 | ArrayList dependencies = new ArrayList(); 57 | Module a = givenModule("A", null, dependencies); 58 | Module b = givenModule("B", a); 59 | dependencies.add(Resource.of(b)); 60 | 61 | Module.sort(asList(a, b)); 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/A_Repository.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import de.is24.deadcode4j.junit.TempFileRule; 4 | import org.junit.Rule; 5 | import org.junit.Test; 6 | 7 | import java.io.IOException; 8 | 9 | @SuppressWarnings("ConstantConditions") 10 | public class A_Repository { 11 | 12 | @Rule 13 | public final TempFileRule tempFileRule = new TempFileRule(); 14 | 15 | @Test(expected = NullPointerException.class) 16 | public void throwsAnExceptionIfTheRepositoryIsNull() throws IOException { 17 | new Repository(null); 18 | } 19 | 20 | @Test(expected = IllegalArgumentException.class) 21 | public void throwsAnExceptionIfTheRepositoryIsNoDirectory() throws IOException { 22 | new Repository(tempFileRule.getTempFile()); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/AnalysisContextBuilder.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import java.util.Collections; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import static com.google.common.collect.Maps.newHashMap; 8 | 9 | public final class AnalysisContextBuilder { 10 | 11 | private AnalysisContextBuilder() { } 12 | 13 | public static AnalysisContext givenAnalysisContext(Module module, Map intermediateResults) { 14 | return new AnalysisContext(module, intermediateResults); 15 | } 16 | 17 | public static AnalysisContext givenAnalysisContext(Module module) { 18 | return givenAnalysisContext(module, Collections.emptyMap()); 19 | } 20 | 21 | public static AnalysisContext givenAnalysisContext(Module module, Object key, IntermediateResult intermediateResult) { 22 | HashMap results = newHashMap(); 23 | results.put(key, intermediateResult); 24 | return givenAnalysisContext(module, results); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/IntermediateResultMapBuilder.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import java.util.Map; 4 | 5 | import static com.google.common.collect.Maps.newHashMap; 6 | 7 | public final class IntermediateResultMapBuilder { 8 | 9 | private IntermediateResultMapBuilder() { } 10 | 11 | public static IntermediateResults.IntermediateResultMap givenIntermediateResultMap(K key, V value) { 12 | Map results = newHashMap(); 13 | results.put(key, value); 14 | return new IntermediateResults.IntermediateResultMap(results); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/ModuleBuilder.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j; 2 | 3 | import com.google.common.base.Function; 4 | 5 | import javax.annotation.Nullable; 6 | import java.io.File; 7 | import java.util.Collection; 8 | import java.util.Collections; 9 | 10 | import static com.google.common.collect.Lists.transform; 11 | import static java.util.Arrays.asList; 12 | 13 | public final class ModuleBuilder { 14 | private ModuleBuilder() { 15 | } 16 | 17 | public static Module givenModule(String moduleId, File repository, Collection dependencies) { 18 | return new Module( 19 | moduleId, 20 | "UTF-8", 21 | dependencies, 22 | repository == null ? null : new Repository(repository), 23 | Collections.emptyList()); 24 | } 25 | 26 | public static Module givenModule(String moduleId, File repository, Module... dependencies) { 27 | return givenModule(moduleId, repository, transform(asList(dependencies), toResource())); 28 | } 29 | 30 | public static Module givenModule(String moduleId, Module... dependencies) { 31 | return givenModule(moduleId, null, dependencies); 32 | } 33 | 34 | public static Module givenModule(String moduleId) { 35 | return givenModule(moduleId, new Module[0]); 36 | } 37 | 38 | private static Function toResource() { 39 | return new Function() { 40 | @Nullable 41 | @Override 42 | public Resource apply(@Nullable Module input) { 43 | return input == null ? null : Resource.of(input); 44 | } 45 | }; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/AByteCodeAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public abstract class AByteCodeAnalyzer extends AnAnalyzer { 6 | 7 | @Test 8 | public void reportsExistenceOfClasses() { 9 | analyzeFile("A.class"); 10 | assertThatClassesAreReported("A"); 11 | 12 | analyzeFile("B.class"); 13 | assertThatClassesAreReported("A", "B"); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_ByteCodeAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import javassist.CtClass; 5 | import org.junit.Test; 6 | 7 | import javax.annotation.Nonnull; 8 | 9 | import static org.hamcrest.MatcherAssert.assertThat; 10 | import static org.hamcrest.Matchers.hasSize; 11 | 12 | public final class A_ByteCodeAnalyzer extends AnAnalyzer { 13 | 14 | @Override 15 | protected ByteCodeAnalyzer createAnalyzer() { 16 | return new ByteCodeAnalyzer() { 17 | @Override 18 | protected void analyzeClass(@Nonnull AnalysisContext analysisContext, @Nonnull CtClass clazz) { 19 | analysisContext.addAnalyzedClass(clazz.getName()); 20 | } 21 | }; 22 | } 23 | 24 | @Test 25 | public void analyzesAClassFile() { 26 | analyzeFile("SingleClass.class"); 27 | 28 | assertThatClassesAreReported("SingleClass"); 29 | assertThatNoDependenciesAreReported(); 30 | } 31 | 32 | @Test 33 | public void doesNotAnalyzeNonClassFile() { 34 | analyzeFile("spring.xml"); 35 | 36 | assertThat("Should analyze no class", analysisContext.getAnalyzedCode().getAnalyzedClasses(), hasSize(0)); 37 | assertThatNoDependenciesAreReported(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_CustomAnnotationsAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.junit.LoggingRule; 4 | import org.apache.maven.plugin.logging.Log; 5 | import org.junit.After; 6 | import org.junit.Test; 7 | import org.mockito.Matchers; 8 | 9 | import static java.util.Collections.singleton; 10 | import static org.mockito.Matchers.anyString; 11 | import static org.mockito.Mockito.*; 12 | 13 | public final class A_CustomAnnotationsAnalyzer extends AnAnalyzer { 14 | 15 | private Log log; 16 | 17 | @Override 18 | public LoggingRule enableLogging() { 19 | log = LoggingRule.createMock(); 20 | return new LoggingRule(log); 21 | } 22 | 23 | @Override 24 | protected CustomAnnotationsAnalyzer createAnalyzer() { 25 | return new CustomAnnotationsAnalyzer(singleton("foo.Bar")); 26 | } 27 | 28 | @After 29 | public void resetMock() { 30 | reset(log); 31 | } 32 | 33 | @Test 34 | public void logsObsoleteInterfaceEntry() { 35 | analyzeFile("AnnotatedClass.class"); 36 | doFinishAnalysis(); 37 | 38 | verify(log).warn(Matchers.contains("foo.Bar")); 39 | } 40 | 41 | @Test 42 | public void doesNotLogInterfaceEntryFoundInClassPath() { 43 | this.objectUnderTest = new CustomAnnotationsAnalyzer(singleton("de.is24.deadcode4j.junit.Annotation")); 44 | 45 | analyzeFile("AnnotatedClass.class"); 46 | doFinishAnalysis(); 47 | 48 | verify(log, never()).warn(anyString()); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_CustomInterfacesAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.junit.LoggingRule; 4 | import org.apache.maven.plugin.logging.Log; 5 | import org.junit.After; 6 | import org.junit.Test; 7 | import org.mockito.Matchers; 8 | 9 | import static java.util.Collections.singleton; 10 | import static org.mockito.Matchers.anyString; 11 | import static org.mockito.Mockito.*; 12 | 13 | public final class A_CustomInterfacesAnalyzer extends AnAnalyzer { 14 | 15 | private Log log; 16 | 17 | @Override 18 | public LoggingRule enableLogging() { 19 | log = LoggingRule.createMock(); 20 | return new LoggingRule(log); 21 | } 22 | 23 | @Override 24 | protected CustomInterfacesAnalyzer createAnalyzer() { 25 | return new CustomInterfacesAnalyzer(singleton("foo.Bar")); 26 | } 27 | 28 | @After 29 | public void resetMock() { 30 | reset(log); 31 | } 32 | 33 | @Test 34 | public void logsObsoleteInterfaceEntry() { 35 | analyzeFile("SomeServletInitializer.class"); 36 | doFinishAnalysis(); 37 | 38 | verify(log).warn(Matchers.contains("foo.Bar")); 39 | } 40 | 41 | @Test 42 | public void doesNotLogInterfaceEntryFoundInClassPath() { 43 | this.objectUnderTest = new CustomInterfacesAnalyzer(singleton("de.is24.deadcode4j.junit.SomeInterface")); 44 | 45 | analyzeFile("SomeServletInitializer.class"); 46 | doFinishAnalysis(); 47 | 48 | verify(log, never()).warn(anyString()); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_CustomSuperClassAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.junit.LoggingRule; 4 | import org.apache.maven.plugin.logging.Log; 5 | import org.junit.After; 6 | import org.junit.Test; 7 | import org.mockito.Matchers; 8 | 9 | import static java.util.Collections.singleton; 10 | import static org.mockito.Matchers.anyString; 11 | import static org.mockito.Mockito.*; 12 | 13 | public final class A_CustomSuperClassAnalyzer extends AnAnalyzer { 14 | 15 | private Log log; 16 | 17 | @Override 18 | public LoggingRule enableLogging() { 19 | log = LoggingRule.createMock(); 20 | return new LoggingRule(log); 21 | } 22 | 23 | @Override 24 | protected CustomSuperClassAnalyzer createAnalyzer() { 25 | return new CustomSuperClassAnalyzer(singleton("foo.Bar")); 26 | } 27 | 28 | @After 29 | public void resetMock() { 30 | reset(log); 31 | } 32 | 33 | @Test 34 | public void logsObsoleteSuperClassEntry() { 35 | analyzeFile("SubClassThatShouldBeLive.class"); 36 | doFinishAnalysis(); 37 | 38 | verify(log).warn(Matchers.contains("foo.Bar")); 39 | } 40 | 41 | @Test 42 | public void doesNotLogSuperClassEntryFoundInClassPath() { 43 | this.objectUnderTest = new CustomSuperClassAnalyzer(singleton("java.lang.Thread")); 44 | 45 | analyzeFile("SubClassThatShouldBeLive.class"); 46 | doFinishAnalysis(); 47 | 48 | verify(log, never()).warn(anyString()); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_JavaFileAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import com.github.javaparser.ast.CompilationUnit; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import javax.annotation.Nonnull; 9 | import java.util.concurrent.atomic.AtomicBoolean; 10 | 11 | import static org.hamcrest.MatcherAssert.assertThat; 12 | import static org.hamcrest.Matchers.is; 13 | 14 | public final class A_JavaFileAnalyzer extends AnAnalyzer { 15 | 16 | private AtomicBoolean didAnalyzeFile; 17 | 18 | @Before 19 | public void setUp() { 20 | this.didAnalyzeFile = new AtomicBoolean(false); 21 | } 22 | 23 | @Override 24 | protected JavaFileAnalyzer createAnalyzer() { 25 | return new JavaFileAnalyzer() { 26 | @Override 27 | protected void analyzeCompilationUnit(@Nonnull AnalysisContext analysisContext, @Nonnull CompilationUnit compilationUnit) { 28 | didAnalyzeFile.set(true); 29 | } 30 | }; 31 | } 32 | 33 | @Test 34 | public void analyzesJavaFiles() { 35 | analyzeFile("../../src/test/java/SingleClass.java"); 36 | 37 | assertThat(didAnalyzeFile.get(), is(true)); 38 | } 39 | 40 | @Test 41 | public void doesNotAnalyzeNonJavaFile() { 42 | analyzeFile("spring.xml"); 43 | 44 | assertThat(didAnalyzeFile.get(), is(false)); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_JerseyWebXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public class A_JerseyWebXmlAnalyzer extends AnAnalyzer { 6 | 7 | @Override 8 | protected JerseyWebXmlAnalyzer createAnalyzer() { 9 | return new JerseyWebXmlAnalyzer(); 10 | } 11 | 12 | @Test 13 | public void shouldParseWebXmlFiles() { 14 | analyzeFile("de/is24/deadcode4j/analyzer/jersey.web.xml"); 15 | assertThatDependenciesAreReported( 16 | "jersey.dummy.filter.Application", 17 | "jersey.dummy.servlet.Application"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_LogbackXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public class A_LogbackXmlAnalyzer extends AnAnalyzer { 6 | 7 | @Override 8 | protected LogbackXmlAnalyzer createAnalyzer() { 9 | return new LogbackXmlAnalyzer(); 10 | } 11 | 12 | @Test 13 | public void shouldParseLogbackFiles() { 14 | analyzeFile("de/is24/deadcode4j/analyzer/logback.xml"); 15 | 16 | assertThatDependenciesAreReported( 17 | "de.is24.deadcode4j.logback.Appender", 18 | "de.is24.deadcode4j.logback.ContextListener", 19 | "de.is24.deadcode4j.logback.CustomAction", 20 | "de.is24.deadcode4j.logback.CustomClass", 21 | "de.is24.deadcode4j.logback.Property", 22 | "de.is24.deadcode4j.logback.StatusListener" 23 | ); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_MainClassAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public final class A_MainClassAnalyzer extends AByteCodeAnalyzer { 6 | 7 | @Override 8 | protected MainClassAnalyzer createAnalyzer() { 9 | return new MainClassAnalyzer(); 10 | } 11 | 12 | @Test 13 | public void reportsMainClassAsBeingUsed() { 14 | analyzeFile("MainClass.class"); 15 | 16 | assertThatDependenciesAreReported("MainClass"); 17 | } 18 | 19 | @Test 20 | public void doesNotReportNonMainClassAsBeingUsed() { 21 | analyzeFile("SingleClass.class"); 22 | 23 | assertThatNoDependenciesAreReported(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_ServletContainerInitializerAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public class A_ServletContainerInitializerAnalyzer extends AnAnalyzer { 6 | 7 | @Override 8 | protected ServletContainerInitializerAnalyzer createAnalyzer() { 9 | return new ServletContainerInitializerAnalyzer("JUnit", "de.is24.deadcode4j.junit.SomeInterface") { 10 | }; 11 | } 12 | 13 | @Test 14 | public void shouldRecognizeServletContainerInitializerClasses() { 15 | analyzeFile("de/is24/deadcode4j/analyzer/v3-metadata-missing.web.xml"); 16 | analyzeFile("SomeServletInitializer.class"); 17 | 18 | assertThatDependenciesAreReported("SomeServletInitializer"); 19 | } 20 | 21 | @Test 22 | public void shouldRecognizeServletContainerInitializerClassesIfMetadataCompleteAttributeIsFalse() { 23 | analyzeFile("de/is24/deadcode4j/analyzer/v3-metadata-incomplete.web.xml"); 24 | analyzeFile("SomeServletInitializer.class"); 25 | 26 | assertThatDependenciesAreReported("SomeServletInitializer"); 27 | } 28 | 29 | @Test 30 | public void shouldRecognizeMetadataCompleteAttribute() { 31 | analyzeFile("de/is24/deadcode4j/analyzer/v3-metadata-complete.web.xml"); 32 | analyzeFile("SomeServletInitializer.class"); 33 | 34 | assertThatNoDependenciesAreReported(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_SpringDataCustomRepositoriesAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | import static com.google.common.collect.Sets.newHashSet; 6 | import static de.is24.deadcode4j.AnalysisContextBuilder.givenAnalysisContext; 7 | import static de.is24.deadcode4j.IntermediateResults.resultSetFor; 8 | 9 | public class A_SpringDataCustomRepositoriesAnalyzer extends AByteCodeAnalyzer { 10 | 11 | @Override 12 | protected SpringDataCustomRepositoriesAnalyzer createAnalyzer() { 13 | return new SpringDataCustomRepositoriesAnalyzer(); 14 | } 15 | 16 | @Test 17 | public void recognizesCustomRepository() { 18 | analyzeFile("de/is24/deadcode4j/analyzer/customrepositories/FooRepository.class"); 19 | analyzeFile("de/is24/deadcode4j/analyzer/customrepositories/FooRepositoryCustom.class"); 20 | analyzeFile("de/is24/deadcode4j/analyzer/customrepositories/FooRepositoryImpl.class"); 21 | doFinishAnalysis(); 22 | 23 | assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.customrepositories.FooRepository", 24 | "de.is24.deadcode4j.analyzer.customrepositories.FooRepositoryImpl"); 25 | } 26 | 27 | @Test 28 | public void storesCustomRepositoryInterfacesAsIntermediateResults() { 29 | analyzeFile("de/is24/deadcode4j/analyzer/customrepositories/FooRepository.class"); 30 | 31 | assertThatIntermediateResultIsStored(); 32 | } 33 | 34 | @Test 35 | public void reportsImplementationsOfIntermediateResults() { 36 | this.analysisContext = givenAnalysisContext( 37 | this.analysisContext.getModule(), 38 | this.objectUnderTest.getClass(), 39 | resultSetFor(newHashSet("de.is24.deadcode4j.analyzer.customrepositories.FooRepositoryCustom"))); 40 | 41 | analyzeFile("de/is24/deadcode4j/analyzer/customrepositories/FooRepositoryImpl.class"); 42 | 43 | assertThatDependenciesAreReportedFor("de.is24.deadcode4j.analyzer.customrepositories.FooRepository", 44 | "de.is24.deadcode4j.analyzer.customrepositories.FooRepositoryImpl"); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_SpringNamespaceHandlerAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.mockito.Mockito; 6 | import org.powermock.api.mockito.PowerMockito; 7 | import org.powermock.core.classloader.annotations.PrepareForTest; 8 | import org.powermock.modules.junit4.PowerMockRunner; 9 | 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.util.Properties; 13 | 14 | import static org.hamcrest.MatcherAssert.assertThat; 15 | import static org.hamcrest.Matchers.containsString; 16 | import static org.junit.Assert.fail; 17 | import static org.mockito.Mockito.doThrow; 18 | 19 | @PrepareForTest({SpringNamespaceHandlerAnalyzer.class}) 20 | @RunWith(PowerMockRunner.class) 21 | public final class A_SpringNamespaceHandlerAnalyzer extends AnAnalyzer { 22 | 23 | private static final String SPRING_HANDLER_FILE = "META-INF/spring.handlers"; 24 | 25 | @Override 26 | protected SpringNamespaceHandlerAnalyzer createAnalyzer() { 27 | return new SpringNamespaceHandlerAnalyzer(); 28 | } 29 | 30 | @Test 31 | public void shouldRecognizeDefinedNamespaceHandlers() { 32 | analyzeFile(SPRING_HANDLER_FILE); 33 | 34 | assertThatDependenciesAreReported("CustomNamespaceHandler", "AnotherNamespaceHandler"); 35 | } 36 | 37 | @Test 38 | public void handlesIOExceptionWhenAnalyzingFile() throws Exception { 39 | Properties mock = Mockito.mock(Properties.class); 40 | doThrow(new IOException("JUnit")).when(mock).load(Mockito.any(InputStream.class)); 41 | PowerMockito.whenNew(Properties.class).withNoArguments().thenReturn(mock); 42 | 43 | try { 44 | analyzeFile(SPRING_HANDLER_FILE); 45 | fail("Should abort analysis!"); 46 | } catch (RuntimeException e) { 47 | assertThat(e.getMessage(), containsString(SPRING_HANDLER_FILE)); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_SpringWebXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Map; 6 | 7 | import static org.hamcrest.MatcherAssert.assertThat; 8 | import static org.hamcrest.Matchers.greaterThan; 9 | 10 | public final class A_SpringWebXmlAnalyzer extends AnAnalyzer { 11 | 12 | @Override 13 | protected SpringWebXmlAnalyzer createAnalyzer() { 14 | return new SpringWebXmlAnalyzer(); 15 | } 16 | 17 | @Test 18 | public void shouldParseWebXmlFiles() { 19 | analyzeFile("de/is24/deadcode4j/analyzer/spring.web.xml"); 20 | 21 | Map> codeDependencies = analysisContext.getAnalyzedCode().getCodeDependencies(); 22 | assertThat("Should have analyzed the web.xml file!", codeDependencies.size(), greaterThan(1)); 23 | 24 | assertThatDependenciesAreReported( 25 | "root.contextClass", 26 | "root.initializerClass", 27 | "root.secondInitializerClass", 28 | "servlet.contextClass", 29 | "servlet.initializerClass", 30 | "SpringXmlBean"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_SpringXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public final class A_SpringXmlAnalyzer extends AnAnalyzer { 6 | 7 | @Override 8 | protected SpringXmlAnalyzer createAnalyzer() { 9 | return new SpringXmlAnalyzer(); 10 | } 11 | 12 | @Test 13 | public void shouldParseSpringFiles() { 14 | analyzeFile("spring.xml"); 15 | 16 | assertThatDependenciesAreReported( 17 | // regular beans 18 | "SpringXmlBean", 19 | // MethodInvokingFactoryBean, 20 | "org.springframework.beans.factory.config.MethodInvokingFactoryBean", 21 | "de.is24.deadcode4j.mifb.Factory", 22 | "de.is24.deadcode4j.mifb.One", 23 | "de.is24.deadcode4j.mifb.Two", 24 | "de.is24.deadcode4j.mifb.Three", 25 | "de.is24.deadcode4j.mifb.Four", 26 | // CXF 27 | "de.is24.deadcode4j.jaxws.One", 28 | "de.is24.deadcode4j.jaxws.Two", 29 | "de.is24.deadcode4j.jaxws.Three", 30 | // JobDetailBean 31 | "org.springframework.scheduling.quartz.JobDetailBean", 32 | "de.is24.deadcode4j.jdb.Factory", 33 | "de.is24.deadcode4j.jdb.One", 34 | "de.is24.deadcode4j.jdb.Two", 35 | // JobDetailFactoryBean 36 | "org.springframework.scheduling.quartz.JobDetailFactoryBean", 37 | "de.is24.deadcode4j.jdfb.Factory", 38 | "de.is24.deadcode4j.jdfb.One", 39 | "de.is24.deadcode4j.jdfb.Two", 40 | // view resolver 41 | "org.springframework.web.servlet.view.UrlBasedViewResolver", 42 | "de.is24.deadcode4j.vr.ViewResolver", 43 | "de.is24.deadcode4j.vr.One", 44 | "de.is24.deadcode4j.vr.Two", 45 | "de.is24.deadcode4j.vr.Three" 46 | ); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_SuperClassAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public final class A_SuperClassAnalyzer extends AByteCodeAnalyzer { 6 | 7 | @Override 8 | protected SuperClassAnalyzer createAnalyzer() { 9 | return new SuperClassAnalyzer("junit", "java.lang.Thread") { 10 | }; 11 | } 12 | 13 | @Test 14 | public void reportsASubClassAsLiveCode() { 15 | objectUnderTest = new SuperClassAnalyzer("junit", "javax.servlet.http.HttpServlet", "java.lang.Thread") { 16 | }; 17 | 18 | analyzeFile("DeadServlet.class"); 19 | analyzeFile("SubClassThatShouldBeLive.class"); 20 | 21 | assertThatDependenciesAreReported("DeadServlet", "SubClassThatShouldBeLive"); 22 | } 23 | 24 | @Test 25 | public void reportsASubClassOfASubClassAsLiveCode() { 26 | analyzeFile("SubClassOfSubClassThatShouldBeLive.class"); 27 | 28 | assertThatDependenciesAreReported("SubClassOfSubClassThatShouldBeLive"); 29 | } 30 | 31 | @Test 32 | public void doesNotReportASubClassWithIrrelevantSuperClass() { 33 | analyzeFile("DeadServlet.class"); 34 | analyzeFile("SubClassThatShouldBeLive.class"); 35 | 36 | assertThatDependenciesAreReported("SubClassThatShouldBeLive"); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_TldAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public final class A_TldAnalyzer extends AnAnalyzer { 6 | 7 | @Override 8 | protected TldAnalyzer createAnalyzer() { 9 | return new TldAnalyzer(); 10 | } 11 | 12 | @Test 13 | public void shouldParseTldFiles() { 14 | analyzeFile("taglib.tld"); 15 | 16 | assertThatDependenciesAreReported( 17 | "TagClass", 18 | "TagExtraInfo", 19 | "TagLibraryValidator", 20 | "TldFunction", 21 | "WebAppListener"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/A_WebXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public final class A_WebXmlAnalyzer extends AnAnalyzer { 6 | 7 | @Override 8 | protected WebXmlAnalyzer createAnalyzer() { 9 | return new WebXmlAnalyzer(); 10 | } 11 | 12 | @Test 13 | public void shouldParseWebXmlFiles() { 14 | analyzeFile("web.xml"); 15 | 16 | assertThatDependenciesAreReported( 17 | "WebAppListener", 18 | "WebAppFilter", 19 | "WebAppServlet"); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/An_AnnotationsAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public final class An_AnnotationsAnalyzer extends AByteCodeAnalyzer { 6 | 7 | @Override 8 | protected AnnotationsAnalyzer createAnalyzer() { 9 | return new AnnotationsAnalyzer("junit", "de.is24.deadcode4j.junit.Annotation") { 10 | }; 11 | } 12 | 13 | @Test 14 | public void reportsAnnotatedClassAsBeingUsed() { 15 | objectUnderTest = new AnnotationsAnalyzer("junit", "de.is24.deadcode4j.junit.Annotation", "java.lang.Deprecated") { 16 | }; 17 | 18 | analyzeFile("AnnotatedClass.class"); 19 | analyzeFile("DeadServlet.class"); 20 | 21 | assertThatDependenciesAreReported("AnnotatedClass", "DeadServlet"); 22 | } 23 | 24 | @Test 25 | public void reportsClassAnnotatedWithAnnotatedAnnotationAsBeingUsed() { 26 | analyzeFile("ClassAnnotatedWithAnnotatedAnnotation.class"); 27 | 28 | assertThatDependenciesAreReported("ClassAnnotatedWithAnnotatedAnnotation"); 29 | } 30 | 31 | @Test 32 | public void reportsSubClassOfClassBeingAnnotatedWithAnnotationMarkedAsInheritedAsBeingUsed() { 33 | analyzeFile("SubClassOfAnnotatedClass.class"); 34 | 35 | assertThatDependenciesAreReported("SubClassOfAnnotatedClass"); 36 | } 37 | 38 | @Test 39 | public void doesNotReportUnannotatedClassAsBeingUsed() { 40 | analyzeFile("AnnotatedClass.class"); 41 | analyzeFile("DeadServlet.class"); 42 | 43 | assertThatDependenciesAreReported("AnnotatedClass"); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/An_IgnoreClassesAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import com.google.common.collect.Sets; 4 | import de.is24.deadcode4j.DeadCodeComputer; 5 | import de.is24.deadcode4j.junit.LoggingRule; 6 | import org.apache.maven.plugin.logging.Log; 7 | import org.junit.Test; 8 | 9 | import static org.mockito.Mockito.verify; 10 | 11 | public class An_IgnoreClassesAnalyzer extends AByteCodeAnalyzer { 12 | 13 | private Log logMock; 14 | 15 | @Override 16 | public LoggingRule enableLogging() { 17 | logMock = LoggingRule.createMock(); 18 | return new LoggingRule(logMock); 19 | } 20 | 21 | @Override 22 | protected IgnoreClassesAnalyzer createAnalyzer() { 23 | return new IgnoreClassesAnalyzer(new DeadCodeComputer(), Sets.newHashSet("A", "C")); 24 | } 25 | 26 | @Test 27 | public void marksIgnoredClassAsLiveCode() throws Exception { 28 | analyzeFile("A.class"); 29 | doFinishAnalysis(); 30 | 31 | assertThatDependenciesAreReported("A"); 32 | } 33 | 34 | @Test 35 | public void doesNotMarkUnknownClassAsLiveCode() throws Exception { 36 | analyzeFile("B.class"); 37 | doFinishAnalysis(); 38 | 39 | assertThatNoDependenciesAreReported(); 40 | } 41 | 42 | @Test 43 | public void logsThatAClassWasIgnored() throws Exception { 44 | analyzeFile("A.class"); 45 | doFinishAnalysis(); 46 | 47 | verify(logMock).info("Ignoring 1 class(es) which seem(s) to be unused."); 48 | } 49 | 50 | @Test 51 | public void logsThatAnIgnoredClassDoesNotExist() throws Exception { 52 | analyzeFile("A.class"); 53 | doFinishAnalysis(); 54 | 55 | verify(logMock).warn("Class [C] should be ignored, but does not exist. You should remove the configuration entry."); 56 | } 57 | 58 | @Test 59 | public void logsThatAnIgnoredClassIsRequiredAnyway() throws Exception { 60 | analysisContext.addDependencies("B", "A"); 61 | 62 | analyzeFile("A.class"); 63 | doFinishAnalysis(); 64 | 65 | verify(logMock).warn("Class [A] should be ignored, but is not dead. You should remove the configuration entry."); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/An_InterfacesAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer; 2 | 3 | import org.junit.Test; 4 | 5 | public final class An_InterfacesAnalyzer extends AByteCodeAnalyzer { 6 | 7 | @Override 8 | protected InterfacesAnalyzer createAnalyzer() { 9 | return new InterfacesAnalyzer("junit", "java.lang.Cloneable") { 10 | }; 11 | } 12 | 13 | @Test 14 | public void reportsImplementingClassAsBeingUsed() { 15 | objectUnderTest = new InterfacesAnalyzer("junit", "java.lang.Cloneable", "java.io.Serializable") { 16 | }; 17 | 18 | analyzeFile("ClassImplementingCloneable.class"); 19 | analyzeFile("DeadServlet.class"); 20 | 21 | assertThatDependenciesAreReported("ClassImplementingCloneable", "DeadServlet"); 22 | } 23 | 24 | @Test 25 | public void doesNotReportNonImplementingClassAsBeingUsed() { 26 | analyzeFile("ClassImplementingCloneable.class"); 27 | analyzeFile("DeadServlet.class"); 28 | 29 | assertThatDependenciesAreReported("ClassImplementingCloneable"); 30 | } 31 | 32 | @Test 33 | public void reportsSubClassImplementingClassAsBeingUsed() { 34 | objectUnderTest = new InterfacesAnalyzer("junit", "java.lang.Runnable") { 35 | }; 36 | 37 | analyzeFile("SubClassThatShouldBeLive.class"); 38 | 39 | assertThatDependenciesAreReported("SubClassThatShouldBeLive"); 40 | } 41 | 42 | @Test 43 | public void reportsClassImplementingSubInterfaceAsBeingUsed() { 44 | objectUnderTest = new InterfacesAnalyzer("junit", "java.io.Serializable") { 45 | }; 46 | 47 | analyzeFile("ClassImplementingExternalizable.class"); 48 | analyzeFile("SubClassOfClassImplementingExternalizable.class"); 49 | 50 | assertThatDependenciesAreReported( 51 | "ClassImplementingExternalizable", 52 | "SubClassOfClassImplementingExternalizable"); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/classdependency/ClassWithInnerClasses.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.classdependency; 2 | 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassWithInnerClasses { 5 | 6 | public ClassWithInnerClasses() { 7 | new UsedStaticInnerClass(); 8 | } 9 | public static class UnusedStaticInnerClass {} 10 | public static class UsedStaticInnerClass {} 11 | public class UnusedInnerClass {} 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/AnnotationUsingConstantAsDefault.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import java.lang.annotation.ElementType; 3 | import java.lang.annotation.Target; 4 | @SuppressWarnings("UnusedDeclaration") 5 | @Target(ElementType.METHOD) 6 | public @interface AnnotationUsingConstantAsDefault { 7 | String foo() default Constants.FOO; 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/AnonymousClassUsingConstantOfOuterClassInFieldDirectly.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class AnonymousClassUsingConstantOfOuterClassInFieldDirectly { 4 | private static final String FOO = "foo"; 5 | private static final Object OBJECT = new Object() { 6 | static final String BAR = FOO; 7 | Object anotherObject = new Object() { 8 | String barRef = BAR; 9 | Object crazyRef = OBJECT; 10 | String innerFooRef = Inner.INNER_FOO; 11 | }; 12 | }; 13 | private class Inner { 14 | private static final String INNER_FOO = "inner-foo"; 15 | String bar = FOO; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassCallingMethodOfStaticallyImportedConstantInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassCallingMethodOfStaticallyImportedConstantInField { 5 | private String foo = FOO.intern(); 6 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassCallingMethodOnConstantOfImportedClassInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassCallingMethodOnConstantOfImportedClassInField { 4 | private String foo = Constants.FOO.intern(); 5 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassCallingMethodOnConstantOfNestedClassOfImportedClassInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassCallingMethodOnConstantOfNestedClassOfImportedClassInField { 4 | private String foo = Constants.More.STUFF.intern(); 5 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingConstantInExpression { 4 | @Override 5 | public String toString() { 6 | return String.valueOf( "har".equals(Constants.FOO)); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingConstantInField { 4 | public final String foo = Constants.FOO; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingConstantInMethod { 4 | @Override 5 | public String toString() { 6 | return Constants.FOO; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantOfImplementedInterfaceInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingConstantOfImplementedInterfaceInField implements Constants { 4 | public final String foo = FOO; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantOfInnerClassViaStaticImportInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.More.STUFF; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfInnerClassViaStaticImportInField { 5 | public final String foo = STUFF; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantOfSuperclassInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingConstantOfSuperclassInMethod extends Superclass { 4 | @Override 5 | public String toString() { 6 | return FOO; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantViaAsteriskStaticImportInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.*; 3 | 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassUsingConstantViaAsteriskStaticImportInField { 6 | public final String foo = FOO; 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantViaStaticImportInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | import static java.lang.String.valueOf; 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassUsingConstantViaStaticImportInExpression { 6 | @Override 7 | public String toString() { 8 | return valueOf("har".equals(FOO)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantViaStaticImportInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantViaStaticImportInField { 5 | public final String foo = FOO; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantViaStaticImportInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantViaStaticImportInMethod { 5 | @Override 6 | public String toString() { 7 | return FOO; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingConstantViaStaticImportInSwitch.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import java.util.Random; 3 | import static de.is24.deadcode4j.analyzer.constants.Constants.BAR; 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassUsingConstantViaStaticImportInSwitch { 6 | @Override 7 | public String toString() { 8 | int random = new Random().nextInt(); 9 | switch (random) { 10 | case BAR: return "bar"; 11 | default: return "foo"; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingEnumConstantInSwitch.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingEnumConstantInSwitch { 4 | public void foo(EnumUsingConstantInField anEnum) { 5 | switch (anEnum) { 6 | case ENUM: 7 | default: 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingFQConstantInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingFQConstantInExpression { 4 | @Override 5 | public String toString() { 6 | return String.valueOf( "har".equals(de.is24.deadcode4j.analyzer.constants.Constants.FOO)); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingFQConstantInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingFQConstantInField { 4 | public final String foo = de.is24.deadcode4j.analyzer.constants.Constants.FOO; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingFQConstantInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingFQConstantInMethod { 4 | @Override 5 | public String toString() { 6 | return de.is24.deadcode4j.analyzer.constants.Constants.FOO; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingInnerClassOfConstantInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingInnerClassOfConstantInField { 5 | public final String foo = Constants.More.STUFF; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingInnerClassOfConstantViaAsteriskStaticImportInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.*; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingInnerClassOfConstantViaAsteriskStaticImportInField { 5 | public final String foo = More.STUFF; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingInnerClassOfConstantViaStaticImportInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.More; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingInnerClassOfConstantViaStaticImportInField { 5 | public final String foo = More.STUFF; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingNestedConstantOfImplementedInterfaceInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingNestedConstantOfImplementedInterfaceInField implements Constants { 4 | public final String foo = More.STUFF; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingNestedConstantOfSuperclassInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingNestedConstantOfSuperclassInMethod extends Superclass { 4 | @Override 5 | public String toString() { 6 | return More.STUFF; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticImportForConstantWithSameFieldNameBeingDeclaredAfterItIsReferencedInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingStaticImportForConstantWithSameFieldNameBeingDeclaredAfterItIsReferencedInMethod { 5 | @Override 6 | public String toString() { 7 | return FOO; 8 | } 9 | private final String FOO = "test"; 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticImportForConstantWithSameFieldNameDefinedByInnerClassInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassUsingStaticImportForConstantWithSameFieldNameDefinedByInnerClassInMethod { 6 | private int bar = 42; 7 | @Override 8 | public String toString() { 9 | return FOO; 10 | } 11 | private class InnerClass { 12 | private final String FOO = "test"; 13 | 14 | @Override 15 | public String toString() { 16 | return "" + bar; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticImportForConstantWithSameFieldNameInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingStaticImportForConstantWithSameFieldNameInMethod { 5 | private final String FOO = "test"; 6 | @Override 7 | public String toString() { 8 | return FOO; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticImportForConstantWithSameLocalNameInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingStaticImportForConstantWithSameLocalNameInMethod { 5 | @Override 6 | public String toString() { 7 | @SuppressWarnings("UnnecessaryLocalVariable") 8 | String FOO = "test"; 9 | return FOO; 10 | } 11 | 12 | private static class InnerClass { 13 | public final String foo = FOO; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticImportForConstantWithSameLocalNameInStaticInitializer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassUsingStaticImportForConstantWithSameLocalNameInStaticInitializer { 6 | static { 7 | do { 8 | String FOO = "test"; 9 | FOO.notify(); 10 | } while (false); 11 | } 12 | 13 | private static class InnerClass { 14 | public final String foo = FOO; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticImportForConstantWithSameLocalNameInSuperiorBlocksMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import java.util.Random; 3 | 4 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 5 | 6 | @SuppressWarnings("UnusedDeclaration") 7 | public class ClassUsingStaticImportForConstantWithSameLocalNameInSuperiorBlocksMethod { 8 | @Override 9 | public String toString() { 10 | @SuppressWarnings("UnnecessaryLocalVariable") 11 | String FOO = "test"; 12 | do { 13 | if (new Random().nextBoolean()) { 14 | int i = 4 + 3; 15 | return FOO; 16 | } 17 | } while (true); 18 | } 19 | private static class InnerClass { 20 | public final String foo = FOO; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticImportForConstantWithSameStaticFieldNameInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingStaticImportForConstantWithSameStaticFieldNameInMethod { 5 | private static final String FOO = "test"; 6 | @Override 7 | public String toString() { 8 | return FOO; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticMethodInStaticField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import org.slf4j.Logger; 3 | import static org.slf4j.LoggerFactory.getLogger; 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassUsingStaticMethodInStaticField { 6 | private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(ClassUsingStaticMethodInStaticField.class); 7 | private final Logger logger = getLogger(getClass()); 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticMethodOfNestedClassInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingStaticMethodOfNestedClassInMethod { 4 | public ClassUsingStaticMethodOfNestedClassInMethod() { 5 | Constants.Inner.call(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassUsingStaticMethodOfStaticallyImportedClassInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.Inner; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingStaticMethodOfStaticallyImportedClassInMethod { 5 | public ClassUsingStaticMethodOfStaticallyImportedClassInMethod() { 6 | Inner.call(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ClassWithInnerClassNamedLikePotentialTarget.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassWithInnerClassNamedLikePotentialTarget { 4 | public final String foo = Constants.FOO; 5 | private static interface Constants { 6 | public static final String FOO = "bar"; 7 | } 8 | public static class InnerClass { 9 | public final String foo = Constants.FOO; 10 | } 11 | public static class AnotherInnerClass { 12 | public final String foo = de.is24.deadcode4j.analyzer.constants.Constants.FOO; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/Constants.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | 3 | public interface Constants { 4 | String FOO = "foo"; 5 | int BAR = 42; 6 | 7 | public interface More { 8 | String STUFF = "acme"; 9 | } 10 | 11 | public class Inner { 12 | public static void call() {} 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/EnumUsingConstantInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | 3 | @SuppressWarnings("UnusedDeclaration") 4 | public enum EnumUsingConstantInField { 5 | ENUM; 6 | public final String foo = Constants.FOO; 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/InnerClassUsingConstantOfImplementedInterfaceInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static java.lang.String.valueOf; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class InnerClassUsingConstantOfImplementedInterfaceInExpression implements Constants { 5 | public static class InnerClass { 6 | @Override 7 | public String toString() { 8 | return valueOf("har".equals(FOO)); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/InnerClassUsingConstantOfOuterClassInFieldDirectly.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class InnerClassUsingConstantOfOuterClassInFieldDirectly { 4 | public static final String FOO = "foo"; 5 | private static class InnerClass { 6 | private final String bar = FOO; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/InnerClassUsingConstantOfOuterClassInFieldViaQualifier.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class InnerClassUsingConstantOfOuterClassInFieldViaQualifier { 4 | public static final String FOO = "foo"; 5 | private static class InnerClass { 6 | private final String bar = InnerClassUsingConstantOfOuterClassInFieldViaQualifier.FOO; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/InnerClassUsingNestedConstantOfImplementedInterfaceInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | import static java.lang.String.valueOf; 3 | 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class InnerClassUsingNestedConstantOfImplementedInterfaceInExpression implements Constants { 6 | public static class InnerClass { 7 | @Override 8 | public String toString() { 9 | return valueOf("har".equals(More.STUFF)); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ReferenceToInheritedConstant.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ReferenceToInheritedConstant extends Superclass { 4 | private int i = numbers.length; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/ReferenceToInheritedNonConstant.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ReferenceToInheritedNonConstant extends Superclass { 4 | private int i = strings.length; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/Superclass.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants; 2 | public class Superclass implements Constants { 3 | public static final Number[] numbers = new Number[0]; 4 | public String[] strings = new String[0]; 5 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageInExpression { 5 | @Override 6 | public String toString() { 7 | return String.valueOf( "har".equals(Constants.FOO)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | 3 | import de.is24.deadcode4j.analyzer.constants.Constants; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class ClassUsingConstantOfOtherPackageInField { 7 | public final String foo = Constants.FOO; 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageInMethod { 5 | @Override 6 | public String toString() { 7 | return Constants.FOO; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageViaAsteriskImportInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.*; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageViaAsteriskImportInExpression { 5 | @Override 6 | public String toString() { 7 | return String.valueOf("har".equals(Constants.FOO)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageViaAsteriskImportInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.*; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageViaAsteriskImportInField { 5 | public final String foo = Constants.FOO; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageViaAsteriskImportInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.*; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageViaAsteriskImportInMethod { 5 | @Override 6 | public String toString() { 7 | return Constants.FOO; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageViaAsteriskStaticImportInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.*; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageViaAsteriskStaticImportInField { 5 | public final String foo = FOO; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageViaStaticImportInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageViaStaticImportInExpression { 5 | @Override 6 | public String toString() { 7 | return String.valueOf( "har".equals(FOO)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageViaStaticImportInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageViaStaticImportInField { 5 | public final String foo = FOO; 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingConstantOfOtherPackageViaStaticImportInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import static de.is24.deadcode4j.analyzer.constants.Constants.FOO; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingConstantOfOtherPackageViaStaticImportInMethod { 5 | @Override 6 | public String toString() { 7 | return FOO; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingFQConstantOfOtherPackageInExpression.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingFQConstantOfOtherPackageInExpression { 4 | @Override 5 | public String toString() { 6 | return String.valueOf( "har".equals(de.is24.deadcode4j.analyzer.constants.Constants.FOO)); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingFQConstantOfOtherPackageInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingFQConstantOfOtherPackageInField { 4 | public final String foo = de.is24.deadcode4j.analyzer.constants.Constants.FOO; 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingFQConstantOfOtherPackageInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class ClassUsingFQConstantOfOtherPackageInMethod { 4 | @Override 5 | public String toString() { 6 | @SuppressWarnings("UnnecessaryLocalVariable") 7 | String localVariable = de.is24.deadcode4j.analyzer.constants.Constants.FOO; 8 | return localVariable; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingImportForConstantWithSameFieldNameInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingImportForConstantWithSameFieldNameInMethod { 5 | private ClassWithAccessibleField Constants = new ClassWithAccessibleField(); 6 | @Override 7 | public String toString() { 8 | return Constants.something; 9 | } 10 | private static class ClassWithAccessibleField { 11 | public final String something = "something"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingImportForConstantWithSameLocalNameInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingImportForConstantWithSameLocalNameInMethod { 5 | @Override 6 | public String toString() { 7 | @SuppressWarnings("UnnecessaryLocalVariable") 8 | ClassWithAccessibleField Constants = new ClassWithAccessibleField(); 9 | return Constants.something; 10 | } 11 | private static class InnerClass { 12 | public final String foo = Constants.FOO; 13 | } 14 | private static class ClassWithAccessibleField { 15 | public final String something = "something"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingImportForConstantWithSameParameterNameInCatchClause.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | 4 | @SuppressWarnings({"UnusedDeclaration", "ResultOfMethodCallIgnored"}) 5 | public class ClassUsingImportForConstantWithSameParameterNameInCatchClause { 6 | public String foo() { 7 | try { 8 | return null; 9 | } catch (ClassWithAccessibleField Constants) { 10 | return Constants.something; 11 | } 12 | } 13 | private static class ClassWithAccessibleField extends RuntimeException { 14 | public final String something = "something"; 15 | } 16 | private static class InnerClass { 17 | public final String foo = Constants.FOO; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingImportForConstantWithSameParameterNameInConstructor.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | @SuppressWarnings({"UnusedDeclaration", "ResultOfMethodCallIgnored"}) 4 | public class ClassUsingImportForConstantWithSameParameterNameInConstructor { 5 | public ClassUsingImportForConstantWithSameParameterNameInConstructor(ClassWithAccessibleField Constants) { 6 | String temp = Constants.something; 7 | temp.intern(); 8 | } 9 | private static class ClassWithAccessibleField { 10 | public final String something = "something"; 11 | } 12 | private static class InnerClass { 13 | public final String foo = Constants.FOO; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingImportForConstantWithSameParameterNameInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassUsingImportForConstantWithSameParameterNameInMethod { 6 | public String foo(ClassWithAccessibleField Constants) { 7 | return Constants.something; 8 | } 9 | private static class ClassWithAccessibleField { 10 | public final String something = "something"; 11 | } 12 | private static class InnerClass { 13 | public final String foo = Constants.FOO; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingImportForConstantWithSameStaticFieldNameInMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassUsingImportForConstantWithSameStaticFieldNameInMethod { 5 | private static final ClassWithAccessibleField Constants = new ClassWithAccessibleField(); 6 | @Override 7 | public String toString() { 8 | return Constants.something; 9 | } 10 | private static class ClassWithAccessibleField { 11 | public final String something = "something"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/ClassUsingInnerClassOfConstantOfOtherPackageInField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | 3 | import de.is24.deadcode4j.analyzer.constants.Constants; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class ClassUsingInnerClassOfConstantOfOtherPackageInField { 7 | public final String foo = Constants.More.STUFF; 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/constants/subpackage/EnumUsingImportForConstantWithSameEnumName.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.constants.subpackage; 2 | import de.is24.deadcode4j.analyzer.constants.Constants; 3 | @SuppressWarnings({"UnusedDeclaration"}) 4 | public enum EnumUsingImportForConstantWithSameEnumName { 5 | Constants, 6 | Other; 7 | public final String FOO = "bar"; 8 | private static class InnerClass { 9 | public final String foo = Constants.FOO; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/customrepositories/Foo.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.customrepositories; 2 | public class Foo { } 3 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/customrepositories/FooRepository.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.customrepositories; 2 | import org.springframework.data.repository.CrudRepository; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public interface FooRepository extends CrudRepository, FooRepositoryCustom { } 5 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/customrepositories/FooRepositoryCustom.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.customrepositories; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public interface FooRepositoryCustom { 4 | Foo findByObject(Object o); 5 | } 6 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/customrepositories/FooRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.customrepositories; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class FooRepositoryImpl implements FooRepositoryCustom { 4 | @Override 5 | public Foo findByObject(Object o) { 6 | return new Foo(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/AnotherEntity.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import org.hibernate.annotations.Type; 4 | 5 | public class AnotherEntity { 6 | 7 | @Type(type = "shortClass") 8 | private Number id; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/AnotherEntityWithGeneratedValue.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import javax.persistence.GeneratedValue; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class AnotherEntityWithGeneratedValue { 7 | @GeneratedValue(generator = "generatorThree") 8 | private String getId() { 9 | return null; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/ClassDefiningGenericGenerator.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | import org.hibernate.annotations.GenericGenerator; 3 | @SuppressWarnings("UnusedDeclaration") 4 | @GenericGenerator(name = "aGenerator", strategy = "CompletelyUnknownClass") 5 | public class ClassDefiningGenericGenerator { 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingGeneratedValueAtField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import javax.persistence.GeneratedValue; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class ClassUsingGeneratedValueAtField { 7 | @GeneratedValue(generator = "aGenerator") 8 | private String id; 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingGeneratedValueAtMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import javax.persistence.GeneratedValue; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class ClassUsingGeneratedValueAtMethod { 7 | @GeneratedValue(generator = "aGenerator") 8 | private String getId() { 9 | return null; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingTypeAtField.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import org.hibernate.annotations.Type; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class ClassUsingTypeAtField { 7 | @Type(type = "aRandomType") 8 | private String id; 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingTypeAtMethod.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import org.hibernate.annotations.Type; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class ClassUsingTypeAtMethod { 7 | @Type(type = "aRandomType") 8 | private String getId() { 9 | return "foo"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/ClassUsingTypeWithoutTypeDef.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import org.hibernate.annotations.Type; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class ClassUsingTypeWithoutTypeDef { 7 | @Type(type = "IndependentClass") 8 | private Number id; 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/ClassWithDuplicatedTypeDef.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import org.hibernate.annotations.TypeDef; 4 | 5 | @SuppressWarnings("unused") 6 | @TypeDef(name = "aRandomType", typeClass = String.class) 7 | public class ClassWithDuplicatedTypeDef { 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/ClassWithTypeDef.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import org.hibernate.annotations.TypeDef; 4 | 5 | @TypeDef(name = "aRandomType", typeClass = String.class) 6 | public class ClassWithTypeDef { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/Entity.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import org.hibernate.annotations.Type; 4 | 5 | public class Entity { 6 | 7 | @Type(type = "byteClass") 8 | private Number id; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/EntityWithGeneratedValue.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations; 2 | 3 | import javax.persistence.GeneratedValue; 4 | 5 | @SuppressWarnings("UnusedDeclaration") 6 | public class EntityWithGeneratedValue { 7 | @GeneratedValue(generator = "generatorOne") 8 | private String id; 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/knownStrategies/ClassDefiningGenericGenerator.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.hibernateannotations.knownStrategies; 2 | import org.hibernate.annotations.GenericGenerator; 3 | @SuppressWarnings("UnusedDeclaration") 4 | @GenericGenerator(name = "aGenerator", strategy = "IndependentClass") 5 | public class ClassDefiningGenericGenerator { 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/knownStrategies/package-info.java: -------------------------------------------------------------------------------- 1 | @GenericGenerators({ 2 | @GenericGenerator(name = "generatorOne", strategy = "IndependentClass"), 3 | @GenericGenerator(name = "generatorTwo", strategy = "uuid"), 4 | @GenericGenerator(name = "generatorThree", strategy = "DependingClass") 5 | }) 6 | @TypeDefs({ 7 | @TypeDef(name = "byteClass", typeClass = Byte.class), 8 | @TypeDef(name = "shortClass", typeClass = Short.class)}) package de.is24.deadcode4j.analyzer.hibernateannotations.knownStrategies; 9 | import org.hibernate.annotations.GenericGenerator; 10 | import org.hibernate.annotations.GenericGenerators; 11 | import org.hibernate.annotations.TypeDef; 12 | import org.hibernate.annotations.TypeDefs; -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/hibernateannotations/package-info.java: -------------------------------------------------------------------------------- 1 | @GenericGenerators({ 2 | @GenericGenerator(name = "generatorOne", strategy = "CompletelyUnknownClass"), 3 | @GenericGenerator(name = "generatorTwo", strategy = "uuid"), 4 | @GenericGenerator(name = "generatorThree", strategy = "AnotherCompletelyUnknownClass") 5 | }) 6 | @TypeDefs({ 7 | @TypeDef(name = "byteClass", typeClass = Byte.class), 8 | @TypeDef(name = "shortClass", typeClass = Short.class)}) package de.is24.deadcode4j.analyzer.hibernateannotations; 9 | 10 | import org.hibernate.annotations.GenericGenerator; 11 | import org.hibernate.annotations.GenericGenerators; 12 | import org.hibernate.annotations.TypeDef; 13 | import org.hibernate.annotations.TypeDefs; -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/typeerasure/ClassWithAnonymousClasses.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.typeerasure; 2 | import de.is24.deadcode4j.junit.SomeInterface; 3 | 4 | import java.util.ArrayList; 5 | import java.util.Set; 6 | import java.util.concurrent.Callable; 7 | 8 | @SuppressWarnings("UnusedDeclaration") 9 | public class ClassWithAnonymousClasses { 10 | private Runnable runnable = new Runnable() { 11 | @Override 12 | public void run() { 13 | new ArrayList(); 14 | new Callable() { 15 | @Override 16 | public Integer call() throws Exception { 17 | return null; 18 | } 19 | }; 20 | new Object() { 21 | @Override 22 | public String toString() { 23 | new ArrayList(); 24 | return super.toString(); 25 | } 26 | }; 27 | class AnonymousInner { 28 | private ArrayList aList; 29 | } 30 | } 31 | }; 32 | private Runnable runnable2 = new Runnable() { 33 | @Override 34 | public void run() { 35 | new ArrayList(); 36 | } 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/typeerasure/ClassWithInheritedType.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.typeerasure; 2 | import de.is24.deadcode4j.junit.SomeInterface; 3 | import java.util.List; 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassWithInheritedType extends TypedArrayList { 6 | private List aList; 7 | public static class Inner implements SomeInterface { 8 | private List aList; 9 | public static class Core { 10 | private List aList; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/typeerasure/ClassWithLowerBoundedWildCard.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.typeerasure; 2 | import java.util.ArrayList; 3 | import java.util.Collection; 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassWithLowerBoundedWildCard { 6 | private ArrayList aList; 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/typeerasure/ClassWithTypesThatShouldNotBeRecognized.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.typeerasure; 2 | import java.util.ArrayList; 3 | @SuppressWarnings("UnusedDeclaration") 4 | public class ClassWithTypesThatShouldNotBeRecognized { 5 | public ClassWithTypesThatShouldNotBeRecognized() { 6 | new ArrayList(); 7 | ArrayList aList; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/typeerasure/ClassWithUpperBoundedWildCard.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.typeerasure; 2 | import java.util.ArrayList; 3 | import java.util.Collection; 4 | @SuppressWarnings("UnusedDeclaration") 5 | public class ClassWithUpperBoundedWildCard { 6 | private ArrayList aList; 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/typeerasure/PackageClass.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.typeerasure; 2 | @SuppressWarnings("UnusedDeclaration") 3 | public class PackageClass { } 4 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/typeerasure/TypedArrayList.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.typeerasure; 2 | import java.util.ArrayList; 3 | import java.util.Map; 4 | import java.util.concurrent.*; 5 | import java.util.regex.*; 6 | import static java.util.ResourceBundle.Control; 7 | @SuppressWarnings("UnusedDeclaration") 8 | public class TypedArrayList extends ArrayList> { 9 | private Map someMap; 10 | @Override 11 | public String toString() { 12 | return new ArrayList().toString(); 13 | } 14 | public static class InnerClass extends ArrayList { 15 | public static class NestedInnerClass {} 16 | } 17 | public static class SecondInnerClass { 18 | public ArrayList something; 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/analyzer/webxml/A_BaseWebXmlAnalyzer.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.analyzer.webxml; 2 | 3 | import de.is24.deadcode4j.AnalysisContext; 4 | import de.is24.deadcode4j.analyzer.AnAnalyzer; 5 | import org.junit.Test; 6 | 7 | import javax.annotation.Nonnull; 8 | 9 | import static java.util.Arrays.asList; 10 | import static org.mockito.Matchers.eq; 11 | import static org.mockito.Mockito.mock; 12 | import static org.mockito.Mockito.verify; 13 | 14 | public class A_BaseWebXmlAnalyzer extends AnAnalyzer{ 15 | private final WebXmlHandler handler = mock(WebXmlHandler.class); 16 | 17 | @Override 18 | protected BaseWebXmlAnalyzer createAnalyzer() { 19 | return new BaseWebXmlAnalyzer() { 20 | @Nonnull 21 | @Override 22 | protected WebXmlHandler createWebXmlHandlerFor(@Nonnull AnalysisContext analysisContext) { 23 | return handler; 24 | } 25 | }; 26 | } 27 | 28 | @Test 29 | public void sendsContextParamEventForAContextParamNode() throws Exception { 30 | analyzeFile("de/is24/deadcode4j/analyzer/webxml/web.xml"); 31 | verify(handler).contextParam( 32 | eq(new Param("dummy name", "dummy value"))); 33 | } 34 | 35 | @Test 36 | public void sendsFilterEventForAFilterNode() throws Exception { 37 | analyzeFile("de/is24/deadcode4j/analyzer/webxml/web.xml"); 38 | verify(handler).filter( 39 | eq("dummy.filter.class"), 40 | eq(asList(new Param("dummy name", "dummy value")))); 41 | } 42 | 43 | @Test 44 | public void sendsListenerEventForAListenerNode() throws Exception { 45 | analyzeFile("de/is24/deadcode4j/analyzer/webxml/web.xml"); 46 | verify(handler).listener("dummy.listener.class"); 47 | } 48 | 49 | @Test 50 | public void sendsServletEventForAServletNode() throws Exception { 51 | analyzeFile("de/is24/deadcode4j/analyzer/webxml/web.xml"); 52 | verify(handler).servlet( 53 | eq("dummy.servlet.class"), 54 | eq(asList(new Param("dummy name", "dummy value")))); 55 | } 56 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/junit/AUtilityClass.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.junit; 2 | 3 | import org.junit.Test; 4 | 5 | import java.lang.reflect.Constructor; 6 | import java.lang.reflect.InvocationTargetException; 7 | 8 | public abstract class AUtilityClass { 9 | 10 | protected abstract Class getType(); 11 | 12 | @Test 13 | public void instantiateClassForTestCoverage() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { 14 | Class clazz = getType(); 15 | Constructor constructor = clazz.getDeclaredConstructor(); 16 | constructor.setAccessible(true); 17 | constructor.newInstance(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/junit/AnnotatedAnnotation.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.junit; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Annotation 9 | @Retention(RetentionPolicy.CLASS) 10 | @Target({ElementType.TYPE}) 11 | public @interface AnnotatedAnnotation { 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/junit/Annotation.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.junit; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Retention(RetentionPolicy.CLASS) 6 | @Target({ElementType.TYPE}) 7 | @Inherited 8 | public @interface Annotation { 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/junit/FileLoader.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.junit; 2 | 3 | import java.io.File; 4 | 5 | public class FileLoader { 6 | 7 | /** Returns a file relative to the test classes' directory. */ 8 | public static File getFile(String fileName) { 9 | Class fileLoaderClass = FileLoader.class; 10 | String classFile = fileLoaderClass.getSimpleName() + ".class"; 11 | String pathToClass = fileLoaderClass.getResource(classFile).getFile(); 12 | String baseDir = pathToClass.substring(0, pathToClass.length() - 13 | (fileLoaderClass.getPackage().getName() + "/" + classFile).length()); 14 | return new File(new File(baseDir), fileName); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/junit/SomeInterface.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.junit; 2 | 3 | public interface SomeInterface { 4 | public static class InnerType { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/junit/TempFileRule.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.junit; 2 | 3 | import org.junit.rules.TestWatcher; 4 | import org.junit.runner.Description; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import static java.io.File.createTempFile; 10 | 11 | public class TempFileRule extends TestWatcher { 12 | 13 | private File tempFile; 14 | 15 | @Override 16 | protected void starting(Description description) { 17 | try { 18 | tempFile = createTempFile("JUnit", ".tmp"); 19 | } catch (IOException e) { 20 | throw new RuntimeException("Failed to create temp file!", e); 21 | } 22 | tempFile.deleteOnExit(); 23 | } 24 | 25 | 26 | @Override 27 | @SuppressWarnings("ResultOfMethodCallIgnored") 28 | protected void finished(Description description) { 29 | if (tempFile != null) { 30 | tempFile.delete(); 31 | } 32 | } 33 | 34 | public File getTempFile() { 35 | return tempFile; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/de/is24/deadcode4j/plugin/stubs/ProjectStub.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.plugin.stubs; 2 | 3 | import org.apache.maven.model.Build; 4 | import org.apache.maven.plugin.testing.stubs.ArtifactStub; 5 | import org.apache.maven.plugin.testing.stubs.MavenProjectStub; 6 | 7 | import java.util.Properties; 8 | 9 | import static com.google.common.collect.Lists.newArrayList; 10 | 11 | public class ProjectStub extends MavenProjectStub { 12 | 13 | private final Properties properties = super.getProperties(); 14 | 15 | public ProjectStub() { 16 | ArtifactStub artifact = new ArtifactStub(); 17 | artifact.setGroupId("de.is24.junit"); 18 | artifact.setArtifactId("project"); 19 | artifact.setVersion("42"); 20 | setArtifact(artifact); 21 | setGroupId(artifact.getGroupId()); 22 | setArtifactId(artifact.getArtifactId()); 23 | setVersion(artifact.getVersion()); 24 | setPackaging("jar"); 25 | 26 | setCompileSourceRoots(newArrayList("src/test/java/")); 27 | 28 | properties.setProperty("project.build.sourceEncoding", "UTF-8"); 29 | } 30 | 31 | @Override 32 | public Properties getProperties() { 33 | return properties; 34 | } 35 | 36 | @SuppressWarnings("UnusedDeclaration") // configured via POM 37 | public void setOutputDirectory(String directory) { 38 | Build build = new Build(); 39 | build.setOutputDirectory(directory); 40 | setBuild(build); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/de/is24/guava/A_NonNullFunctions.java: -------------------------------------------------------------------------------- 1 | package de.is24.guava; 2 | 3 | import com.google.common.base.Optional; 4 | import de.is24.deadcode4j.junit.AUtilityClass; 5 | import org.junit.Test; 6 | 7 | import static com.google.common.base.Optional.absent; 8 | import static com.google.common.base.Optional.of; 9 | import static org.hamcrest.MatcherAssert.assertThat; 10 | import static org.hamcrest.Matchers.is; 11 | import static org.mockito.Matchers.anyObject; 12 | import static org.mockito.Mockito.*; 13 | 14 | public class A_NonNullFunctions extends AUtilityClass { 15 | 16 | @Test 17 | @SuppressWarnings("unchecked") 18 | public void callsEachFunction() { 19 | Object expectedReturnValue = new Object(); 20 | NonNullFunction> first = mock(NonNullFunction.class, "firstFunction"); 21 | when(first.apply(anyObject())).thenReturn(absent()); 22 | NonNullFunction> second = mock(NonNullFunction.class, "secondFunction"); 23 | when(second.apply(anyObject())).thenReturn(of(expectedReturnValue)); 24 | 25 | Optional result = NonNullFunctions.or(first, second).apply(new Object()); 26 | 27 | assertThat(result.isPresent(), is(true)); 28 | assertThat(result.get(), is(expectedReturnValue)); 29 | verify(first).apply(anyObject()); 30 | } 31 | 32 | @Test 33 | @SuppressWarnings("unchecked") 34 | public void stopsAfterResultIsPresent() { 35 | Object expectedReturnValue = new Object(); 36 | NonNullFunction> first = mock(NonNullFunction.class, "firstFunction"); 37 | when(first.apply(anyObject())).thenReturn(of(expectedReturnValue)); 38 | NonNullFunction> second = mock(NonNullFunction.class, "secondFunction"); 39 | when(second.apply(anyObject())).thenReturn(absent()); 40 | 41 | Optional result = NonNullFunctions.or(first, second).apply(new Object()); 42 | 43 | assertThat(result.isPresent(), is(true)); 44 | assertThat(result.get(), is(expectedReturnValue)); 45 | verify(second, never()).apply(anyObject()); 46 | } 47 | 48 | @Override 49 | protected Class getType() { 50 | return NonNullFunctions.class; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/test/java/de/is24/javaparser/An_ImportDeclarations.java: -------------------------------------------------------------------------------- 1 | package de.is24.javaparser; 2 | 3 | import de.is24.deadcode4j.junit.AUtilityClass; 4 | 5 | public class An_ImportDeclarations extends AUtilityClass { 6 | 7 | @Override 8 | protected Class getType() { 9 | return ImportDeclarations.class; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/de/is24/maven/slf4j/An_AbstractSlf4jMojo.java: -------------------------------------------------------------------------------- 1 | package de.is24.maven.slf4j; 2 | 3 | import org.apache.maven.plugin.AbstractMojoExecutionException; 4 | import org.apache.maven.plugin.MojoExecutionException; 5 | import org.apache.maven.plugin.MojoFailureException; 6 | import org.apache.maven.plugin.logging.Log; 7 | import org.junit.Test; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import static org.mockito.Mockito.*; 11 | 12 | public final class An_AbstractSlf4jMojo { 13 | 14 | @Test 15 | public void wrapsMavenLogger() throws MojoFailureException, MojoExecutionException { 16 | Log logMock = mock(Log.class); 17 | when(logMock.isInfoEnabled()).thenReturn(true); 18 | AbstractSlf4jMojo objectUnderTest = new AbstractSlf4jMojo() { 19 | @Override 20 | protected void doExecute() throws MojoExecutionException, MojoFailureException { 21 | LoggerFactory.getLogger(getClass()).info("Hello JUnit!"); 22 | } 23 | }; 24 | objectUnderTest.setLog(logMock); 25 | 26 | objectUnderTest.execute(); 27 | 28 | verify(logMock).info("Hello JUnit!"); 29 | } 30 | 31 | @Test 32 | public void resetsMockEvenWhenExceptionOccurs() { 33 | Log logMock = mock(Log.class); 34 | AbstractSlf4jMojo objectUnderTest = new AbstractSlf4jMojo() { 35 | @Override 36 | protected void doExecute() throws MojoExecutionException, MojoFailureException { 37 | throw new MojoFailureException("FAIL"); 38 | } 39 | }; 40 | objectUnderTest.setLog(logMock); 41 | 42 | try { 43 | objectUnderTest.execute(); 44 | } catch (AbstractMojoExecutionException ignored) { 45 | } 46 | LoggerFactory.getLogger(getClass()).info("Hello JUnit!"); 47 | 48 | verifyZeroInteractions(logMock); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/test/resources/META-INF/spring.handlers: -------------------------------------------------------------------------------- 1 | # suppress inspection "UnusedProperty" for whole file 2 | http\://deadcode4j.org/schema/first=CustomNamespaceHandler 3 | http\://deadcode4j.org/schema/second=AnotherNamespaceHandler -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/empty.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/jersey.web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | Jersey Filter 10 | org.glassfish.jersey.servlet.ServletContainer 11 | 12 | javax.ws.rs.Application 13 | jersey.dummy.filter.Application 14 | 15 | 16 | 17 | Jersey Servlet 18 | com.sun.jersey.spi.spring.container.servlet.SpringServlet 19 | 20 | javax.ws.rs.Application 21 | jersey.dummy.servlet.Application 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/prefixed.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | de.is24.deadcode4j.ClassInElement 6 | de.is24.deadcode4j.FirstClassInAnotherElement 7 | 8 | de.is24.deadcode4j.SecondClassInAnotherElement 9 | 10 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/some.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | de.is24.deadcode4j.ClassInElement 5 | de.is24.deadcode4j.ClassInElement 6 | 7 | de.is24.deadcode4j.ClassInNestedElement 8 | 9 | 10 | 11 | 12 | de.is24.deadcode4j.FirstClassInAnotherElement 13 | de.is24.deadcode4j.SecondClassInAnotherElement 14 | 15 | 16 | 17 | de.is24.deadcode4j.UnlockedClassInElement 18 | de.is24.deadcode4j.LockedClassInElement 19 | 20 | de.is24.deadcode4j.UnlockedClassInUnlockedNestedElement 21 | 22 | 23 | de.is24.deadcode4j.UnlockedClassInLockedNestedElement 24 | 25 | 26 | de.is24.deadcode4j.LockedClassInNestedElement 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/spring.web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | contextClass 10 | root.contextClass 11 | 12 | 13 | contextInitializerClasses 14 | root.initializerClass,root.secondInitializerClass 15 | 16 | 17 | contextConfigLocation 18 | root.contextConfigLocation,SpringXmlBean 19 | 20 | 21 | shouldBeIgnored 22 | root.someValue 23 | 24 | 25 | aServlet 26 | WebAppServlet 27 | 28 | contextClass 29 | servlet.contextClass 30 | 31 | 32 | contextInitializerClasses 33 | servlet.initializerClass 34 | 35 | 36 | ignoreMeToo 37 | servlet.someValue 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/v3-metadata-complete.web.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/v3-metadata-incomplete.web.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/v3-metadata-missing.web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/analyzer/webxml/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | dummy name 11 | 12 | 13 | 14 | dummy value 15 | 16 | 17 | 18 | 19 | 20 | dummy.listener.class 21 | 22 | 23 | 24 | 25 | 26 | dummy filter 27 | 28 | 29 | 30 | dummy.filter.class 31 | 32 | 33 | 34 | 35 | dummy name 36 | 37 | 38 | 39 | dummy value 40 | 41 | 42 | 43 | 44 | 45 | 46 | dummy servlet 47 | 48 | 49 | 50 | dummy.servlet.class 51 | 52 | 53 | 54 | 55 | dummy name 56 | 57 | 58 | 59 | dummy value 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/java8/Lambda.java: -------------------------------------------------------------------------------- 1 | package de.is24.deadcode4j.java8; 2 | 3 | import java.util.HashSet; 4 | import java.util.stream.Stream; 5 | 6 | public class Lambda { 7 | public static void main(String[] args) { 8 | System.out.println(Stream.generate(HashSet::new)); 9 | } 10 | } -------------------------------------------------------------------------------- /src/test/resources/de/is24/deadcode4j/plugin/projects/misconfig.pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | de.is24.junit 7 | project 8 | 42 9 | jar 10 | 11 | 12 | 13 | 14 | de.is24.mavenplugins 15 | deadcode4j-maven-plugin 16 | 17 | 18 | 19 | nospring 20 | .xml 21 | 22 | 23 | true 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/test/resources/nospring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/test/resources/spring-with-prefix.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /src/test/resources/taglib.tld: -------------------------------------------------------------------------------- 1 | 2 | 7 | 42 8 | deadcode4jTld 9 | 10 | 11 | TagLibraryValidator 12 | 13 | 14 | 15 | 16 | WebAppListener 17 | 18 | 19 | 20 | 21 | deadcode4jTag 22 | TagClass 23 | TagExtraInfo 24 | empty 25 | 26 | 27 | 28 | deadcode4jFunction 29 | TldFunction 30 | void foo() 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/test/resources/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | WebAppListener 11 | 12 | 13 | 14 | aFilter 15 | WebAppFilter 16 | 17 | 18 | aServlet 19 | WebAppServlet 20 | 21 | -------------------------------------------------------------------------------- /tools/check-code.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | mvn findbugs:findbugs pmd:cpd-check pmd:check -------------------------------------------------------------------------------- /tools/update-versions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | excludes=javax.servlet:javax.servlet-api # we're using some kind of legacy version here 4 | 5 | mvn versions:update-parent versions:update-properties versions:use-latest-releases -Dexcludes=${excludes} -DgenerateBackupPoms=false -Dmaven.version.rules=file://\${project.basedir}/config/version-rules.xml --------------------------------------------------------------------------------