Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception while parsing Android lint output #93

Closed
stkent opened this issue Jun 23, 2016 · 3 comments
Closed

Exception while parsing Android lint output #93

stkent opened this issue Jun 23, 2016 · 3 comments
Assignees
Labels

Comments

@stkent
Copy link
Collaborator

stkent commented Jun 23, 2016

Gnag version: 1.1
Gnag configuration:

gnag {
    pmd {
        enabled false
    }

    github {
        repoName 'redacted/redacted'
    }
}

Stack trace (recorded output when running ./gradlew clean gnagCheck):

Error reading line number from Android Lint violations.
java.lang.NumberFormatException: For input string: ""
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
        at java.lang.Integer.parseInt(Integer.java:592)
        at java.lang.Integer.valueOf(Integer.java:766)
        at org.codehaus.groovy.runtime.StringGroovyMethods.toInteger(StringGroovyMethods.java:3333)
        at org.codehaus.groovy.runtime.StringGroovyMethods.toInteger(StringGroovyMethods.java:3342)
        at groovy.util.slurpersupport.GPathResult.toInteger(GPathResult.java:281)
        at sun.reflect.GeneratedMethodAccessor97.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1210)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
        at groovy.lang.DelegatingMetaClass.invokeMethod(DelegatingMetaClass.java:151)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
        at com.btkelly.gnag.reporters.AndroidLintViolationDetector$_getDetectedViolations_closure2.doCall(AndroidLintViolationDetector.groovy:65)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
        at groovy.lang.Closure.call(Closure.java:426)
        at groovy.lang.Closure.call(Closure.java:442)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2030)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2015)
        at org.codehaus.groovy.runtime.dgm$158.doMethodInvoke(Unknown Source)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1210)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
        at groovy.lang.DelegatingMetaClass.invokeMethod(DelegatingMetaClass.java:151)
        at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at com.btkelly.gnag.reporters.AndroidLintViolationDetector.getDetectedViolations(AndroidLintViolationDetector.groovy:60)
        at com.btkelly.gnag.tasks.GnagCheck.lambda$executeGnagCheck$2(GnagCheck.java:87)
        at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
        at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
        at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
        at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
        at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
        at com.btkelly.gnag.tasks.GnagCheck.executeGnagCheck(GnagCheck.java:81)
        at com.btkelly.gnag.tasks.GnagCheck.taskAction(GnagCheck.java:71)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:227)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:220)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:209)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:585)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:568)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
        at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
        at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
        at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:154)
        at org.gradle.internal.Factories$1.create(Factories.java:22)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:52)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:151)
        at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:99)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:93)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:93)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:82)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:94)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:43)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:45)
        at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:51)
        at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:28)
        at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:43)
        at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:170)
        at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
        at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
        at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
        at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
        at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
        at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
        at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
        at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
        at org.gradle.launcher.Main.doAction(Main.java:33)
        at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
        at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
        at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30)
        at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:129)
        at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)

Lint output (check the errors of type InvalidPackage; they are missing line/column numbers):

<?xml version="1.0" encoding="UTF-8"?>
<issues format="4" by="lint 25.1.7">

    <issue
        id="InlinedApi"
        severity="Warning"
        message="Field requires API level 23 (current min is 16): `android.view.View#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR`"
        category="Correctness"
        priority="6"
        summary="Using inlined constants on older versions"
        explanation="This check scans through all the Android API field references in the application and flags certain constants, such as static final integers and Strings, which were introduced in later versions. These will actually be copied into the class files rather than being referenced, which means that the value is available even when running on older devices. In some cases that&apos;s fine, and in other cases it can result in a runtime crash or incorrect behavior. It depends on the context, so consider the code carefully and device whether it&apos;s safe and can be suppressed or whether the code needs tbe guarded.

If you really want to use this API and don&apos;t need to support older devices just set the `minSdkVersion` in your `build.gradle` or `AndroidManifest.xml` files.
If your code is *deliberately* accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the `@TargetApi` annotation specifying the local minimum SDK to apply, such as `@TargetApi(11)`, such that this check considers 11 rather than your manifest file&apos;s minimum SDK as the required API level.
"
        errorLine1="import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;"
        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        quickfix="studio,adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/java/com/detroitlabs/redacted/BaseActivity.java"
            line="20"
            column="15"/>
    </issue>

    <issue
        id="InvalidPackage"
        severity="Error"
        message="Invalid package reference in library; not included in Android: `java.nio.file`. Referenced from `okio.Okio`."
        category="Correctness"
        priority="6"
        summary="Package not included in Android"
        explanation="This check scans through libraries looking for calls to APIs that are not included in Android.

When you create Android projects, the classpath is set up such that you can only access classes in the API packages that are included in Android. However, if you add other projects to your libs/ folder, there is no guarantee that those .jar files were built with an Android specific classpath, and in particular, they could be accessing unsupported APIs such as java.applet.

This check scans through library jars and looks for references to API packages that are not included in Android and flags these. This is only an error if your code calls one of the library classes which wind up referencing the unsupported package.">
        <location
            file="/Users/stkent/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio/1.8.0/5ea7af56cc7c567ed9856d99efb30740e9b17ff/okio-1.8.0.jar"/>
    </issue>

    <issue
        id="InvalidPackage"
        severity="Error"
        message="Invalid package reference in library; not included in Android: `java.lang.invoke`. Referenced from `retrofit2.Platform.Java8`."
        category="Correctness"
        priority="6"
        summary="Package not included in Android"
        explanation="This check scans through libraries looking for calls to APIs that are not included in Android.

When you create Android projects, the classpath is set up such that you can only access classes in the API packages that are included in Android. However, if you add other projects to your libs/ folder, there is no guarantee that those .jar files were built with an Android specific classpath, and in particular, they could be accessing unsupported APIs such as java.applet.

This check scans through library jars and looks for references to API packages that are not included in Android and flags these. This is only an error if your code calls one of the library classes which wind up referencing the unsupported package.">
        <location
            file="/Users/stkent/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/retrofit/2.0.2/43eeae0b9fb087bb3194ba59ab63a38a32fbf3e/retrofit-2.0.2.jar"/>
    </issue>

    <issue
        id="OldTargetApi"
        severity="Warning"
        message="Not targeting the latest versions of Android; compatibility modes apply. Consider testing and updating this version. Consult the android.os.Build.VERSION_CODES javadoc for details."
        category="Correctness"
        priority="6"
        summary="Target SDK attribute is not targeting latest version"
        explanation="When your application runs on a version of Android that is more recent than your `targetSdkVersion` specifies that it has been tested with, various compatibility modes kick in. This ensures that your application continues to work, but it may look out of place. For example, if the `targetSdkVersion` is less than 14, your app may get an option button in the UI.

To fix this issue, set the `targetSdkVersion` to the highest available value. Then test your app to make sure everything works correctly. You may want to consult the compatibility notes to see what changes apply to each version you are adding support for: http://developer.android.com/reference/android/os/Build.VERSION_CODES.html"
        url="http://developer.android.com/reference/android/os/Build.VERSION_CODES.html"
        urls="http://developer.android.com/reference/android/os/Build.VERSION_CODES.html"
        errorLine1="        targetSdkVersion 23"
        errorLine2="        ~~~~~~~~~~~~~~~~~~~"
        quickfix="studio">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/build.gradle"
            line="42"
            column="9"/>
    </issue>

    <issue
        id="UnusedAttribute"
        severity="Warning"
        message="Attribute `elevation` is only used in API level 21 and higher (current min is 16)"
        category="Correctness"
        priority="6"
        summary="Attribute unused on older versions"
        explanation="This check finds attributes set in XML files that were introduced in a version newer than the oldest version targeted by your application (with the `minSdkVersion` attribute).

This is not an error; the application will simply ignore the attribute. However, if the attribute is important to the appearance of functionality of your application, you should consider finding an alternative way to achieve the same result with only available attributes, and then you can optionally create a copy of the layout in a layout-vNN folder which will be used on API NN or higher where you can take advantage of the newer attribute.

Note: This check does not only apply to attributes. For example, some tags can be unused too, such as the new `&lt;tag>` element in layouts introduced in API 21."
        errorLine1="            android:elevation=&quot;0dp&quot;"
        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~"
        quickfix="studio">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/activity_login.xml"
            line="56"
            column="13"/>
    </issue>

    <issue
        id="UnusedAttribute"
        severity="Warning"
        message="Attribute `stateListAnimator` is only used in API level 21 and higher (current min is 16)"
        category="Correctness"
        priority="6"
        summary="Attribute unused on older versions"
        explanation="This check finds attributes set in XML files that were introduced in a version newer than the oldest version targeted by your application (with the `minSdkVersion` attribute).

This is not an error; the application will simply ignore the attribute. However, if the attribute is important to the appearance of functionality of your application, you should consider finding an alternative way to achieve the same result with only available attributes, and then you can optionally create a copy of the layout in a layout-vNN folder which will be used on API NN or higher where you can take advantage of the newer attribute.

Note: This check does not only apply to attributes. For example, some tags can be unused too, such as the new `&lt;tag>` element in layouts introduced in API 21."
        errorLine1="            android:stateListAnimator=&quot;@null&quot;"
        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        quickfix="studio">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/activity_login.xml"
            line="57"
            column="13"/>
    </issue>

    <issue
        id="GradleDependency"
        severity="Warning"
        message="A newer version of com.android.support:design than 23.4.0 is available: 24.0.0"
        category="Correctness"
        priority="4"
        summary="Obsolete Gradle Dependency"
        explanation="This detector looks for usages of libraries where the version you are using is not the current stable release. Using older versions is fine, and there are cases where you deliberately want to stick with an older version. However, you may simply not be aware that a more recent version is available, and that is what this lint check helps find."
        errorLine1="    compile &quot;com.android.support:design:23.4.0&quot;"
        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        quickfix="studio">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/build.gradle"
            line="78"
            column="5"/>
    </issue>

    <issue
        id="GradleDynamicVersion"
        severity="Warning"
        message="Avoid using + in version numbers; can lead to unpredictable and unrepeatable builds (io.fabric.tools:gradle:1.+)"
        category="Correctness"
        priority="4"
        summary="Gradle Dynamic Version"
        explanation="Using `+` in dependencies lets you automatically pick up the latest available version rather than a specific, named version. However, this is not recommended; your builds are not repeatable; you may have tested with a slightly different version than what the build server used. (Using a dynamic version as the major version number is more problematic than using it in the minor version position.)"
        errorLine1="        classpath &apos;io.fabric.tools:gradle:1.+&apos;"
        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        quickfix="studio">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/build.gradle"
            line="12"
            column="9"/>
    </issue>

    <issue
        id="AllowBackup"
        severity="Warning"
        message="On SDK version 23 and up, your app data will be automatically backed up and restored on app install. Consider adding the attribute `android:fullBackupContent` to specify an `@xml` resource which configures which files to backup. More info: https://developer.android.com/preview/backup/index.html"
        category="Security"
        priority="3"
        summary="AllowBackup/FullBackupContent Problems"
        explanation="The `allowBackup` attribute determines if an application&apos;s data can be backed up and restored. It is documented at http://developer.android.com/reference/android/R.attr.html#allowBackup

By default, this flag is set to `true`. When this flag is set to `true`, application data can be backed up and restored by the user using `adb backup` and `adb restore`.

This may have security consequences for an application. `adb backup` allows users who have enabled USB debugging to copy application data off of the device. Once backed up, all application data can be read by the user. `adb restore` allows creation of application data from a source specified by the user. Following a restore, applications should not assume that the data, file permissions, and directory permissions were created by the application itself.

Setting `allowBackup=&quot;false&quot;` opts an application out of both backup and restore.

To fix this warning, decide whether your application should support backup, and explicitly set `android:allowBackup=(true|false)&quot;`.

If not set to false, and if targeting API 23 or later, lint will also warn that you should set `android:fullBackupContent` to configure auto backup."
        url="https://developer.android.com/preview/backup/index.html"
        urls="https://developer.android.com/preview/backup/index.html,http://developer.android.com/reference/android/R.attr.html#allowBackup"
        errorLine1="    &lt;application"
        errorLine2="    ^"
        includedVariants="debug"
        excludedVariants="release"
        quickfix="studio,adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/debug/AndroidManifest.xml"
            line="7"
            column="5"/>
    </issue>

    <issue
        id="AllowBackup"
        severity="Warning"
        message="On SDK version 23 and up, your app data will be automatically backed up and restored on app install. Consider adding the attribute `android:fullBackupContent` to specify an `@xml` resource which configures which files to backup. More info: https://developer.android.com/preview/backup/index.html"
        category="Security"
        priority="3"
        summary="AllowBackup/FullBackupContent Problems"
        explanation="The `allowBackup` attribute determines if an application&apos;s data can be backed up and restored. It is documented at http://developer.android.com/reference/android/R.attr.html#allowBackup

By default, this flag is set to `true`. When this flag is set to `true`, application data can be backed up and restored by the user using `adb backup` and `adb restore`.

This may have security consequences for an application. `adb backup` allows users who have enabled USB debugging to copy application data off of the device. Once backed up, all application data can be read by the user. `adb restore` allows creation of application data from a source specified by the user. Following a restore, applications should not assume that the data, file permissions, and directory permissions were created by the application itself.

Setting `allowBackup=&quot;false&quot;` opts an application out of both backup and restore.

To fix this warning, decide whether your application should support backup, and explicitly set `android:allowBackup=(true|false)&quot;`.

If not set to false, and if targeting API 23 or later, lint will also warn that you should set `android:fullBackupContent` to configure auto backup."
        url="https://developer.android.com/preview/backup/index.html"
        urls="https://developer.android.com/preview/backup/index.html,http://developer.android.com/reference/android/R.attr.html#allowBackup"
        errorLine1="    &lt;application"
        errorLine2="    ^"
        quickfix="studio,adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/AndroidManifest.xml"
            line="8"
            column="5"/>
    </issue>

    <issue
        id="AllowBackup"
        severity="Warning"
        message="Should explicitly set `android:allowBackup` to `true` or `false` (it&apos;s `true` by default, and that can have some security implications for the application&apos;s data)"
        category="Security"
        priority="3"
        summary="AllowBackup/FullBackupContent Problems"
        explanation="The `allowBackup` attribute determines if an application&apos;s data can be backed up and restored. It is documented at http://developer.android.com/reference/android/R.attr.html#allowBackup

By default, this flag is set to `true`. When this flag is set to `true`, application data can be backed up and restored by the user using `adb backup` and `adb restore`.

This may have security consequences for an application. `adb backup` allows users who have enabled USB debugging to copy application data off of the device. Once backed up, all application data can be read by the user. `adb restore` allows creation of application data from a source specified by the user. Following a restore, applications should not assume that the data, file permissions, and directory permissions were created by the application itself.

Setting `allowBackup=&quot;false&quot;` opts an application out of both backup and restore.

To fix this warning, decide whether your application should support backup, and explicitly set `android:allowBackup=(true|false)&quot;`.

If not set to false, and if targeting API 23 or later, lint will also warn that you should set `android:fullBackupContent` to configure auto backup."
        url="https://developer.android.com/preview/backup/index.html"
        urls="https://developer.android.com/preview/backup/index.html,http://developer.android.com/reference/android/R.attr.html#allowBackup"
        errorLine1="    &lt;application"
        errorLine2="    ^"
        quickfix="studio,adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/AndroidManifest.xml"
            line="8"
            column="5"/>
    </issue>

    <issue
        id="Overdraw"
        severity="Warning"
        message="Possible overdraw: Root element paints background `@color/brightBlue` with a theme that also paints a background (inferred theme is `@style/AppTheme`)"
        category="Performance"
        priority="3"
        summary="Overdraw: Painting regions more than once"
        explanation="If you set a background drawable on a root view, then you should use a custom theme where the theme background is null. Otherwise, the theme background will be painted first, only to have your custom background completely cover it; this is called &quot;overdraw&quot;.

NOTE: This detector relies on figuring out which layouts are associated with which activities based on scanning the Java code, and it&apos;s currently doing that using an inexact pattern matching algorithm. Therefore, it can incorrectly conclude which activity the layout is associated with and then wrongly complain that a background-theme is hidden.

If you want your custom background on multiple pages, then you should consider making a custom theme with your custom background and just using that theme instead of a root element background.

Of course it&apos;s possible that your custom drawable is translucent and you want it to be mixed with the background. However, you will get better performance if you pre-mix the background with your drawable and use that resulting image or color as a custom theme background instead.
"
        errorLine1="    android:background=&quot;@color/brightBlue&quot;>"
        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/activity_login.xml"
            line="8"
            column="5"/>
    </issue>

    <issue
        id="UnusedResources"
        severity="Warning"
        message="The resource `R.color.darkBlue` appears to be unused"
        category="Performance"
        priority="3"
        summary="Unused resources"
        explanation="Unused resources make applications larger and slow down builds."
        errorLine1="    &lt;color name=&quot;darkBlue&quot;>#067CAD&lt;/color>"
        errorLine2="           ~~~~~~~~~~~~~~~">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/values/colors.xml"
            line="7"
            column="12"/>
    </issue>

    <issue
        id="UnusedResources"
        severity="Warning"
        message="The resource `R.dimen.default_screen_padding` appears to be unused"
        category="Performance"
        priority="3"
        summary="Unused resources"
        explanation="Unused resources make applications larger and slow down builds."
        errorLine1="    &lt;dimen name=&quot;default_screen_padding&quot;>16dp&lt;/dimen>"
        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/values/dimens.xml"
            line="3"
            column="12"/>
    </issue>

    <issue
        id="GoogleAppIndexingWarning"
        severity="Warning"
        message="App is not indexable by Google Search; consider adding at least one Activity with an ACTION-VIEW intent-filler. See issue explanation for more details."
        category="Usability"
        priority="5"
        summary="Missing support for Google App Indexing"
        explanation="Adds URLs to get your app into the Google index, to get installs and traffic to your app from Google Search."
        url="https://g.co/AppIndexing/AndroidStudio"
        urls="https://g.co/AppIndexing/AndroidStudio"
        errorLine1="    &lt;application"
        errorLine2="    ^"
        includedVariants="debug"
        excludedVariants="release"
        quickfix="studio">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/debug/AndroidManifest.xml"
            line="7"
            column="5"/>
    </issue>

    <issue
        id="GoogleAppIndexingWarning"
        severity="Warning"
        message="App is not indexable by Google Search; consider adding at least one Activity with an ACTION-VIEW intent-filler. See issue explanation for more details."
        category="Usability"
        priority="5"
        summary="Missing support for Google App Indexing"
        explanation="Adds URLs to get your app into the Google index, to get installs and traffic to your app from Google Search."
        url="https://g.co/AppIndexing/AndroidStudio"
        urls="https://g.co/AppIndexing/AndroidStudio"
        errorLine1="    &lt;application"
        errorLine2="    ^"
        quickfix="studio">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/AndroidManifest.xml"
            line="8"
            column="5"/>
    </issue>

    <issue
        id="ContentDescription"
        severity="Warning"
        message="[Accessibility] Missing `contentDescription` attribute on image"
        category="Accessibility"
        priority="3"
        summary="Image without `contentDescription`"
        explanation="Non-textual widgets like ImageViews and ImageButtons should use the `contentDescription` attribute to specify a textual description of the widget such that screen readers and other accessibility tools can adequately describe the user interface.

Note that elements in application screens that are purely decorative and do not provide any content or enable a user action should not have accessibility content descriptions. In this case, just suppress the lint warning with a tools:ignore=&quot;ContentDescription&quot; attribute.

Note that for text fields, you should not set both the `hint` and the `contentDescription` attributes since the hint will never be shown. Just set the `hint`. See http://developer.android.com/guide/topics/ui/accessibility/checklist.html#special-cases."
        errorLine1="    &lt;ImageView"
        errorLine2="    ^"
        quickfix="studio,adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/activity_login.xml"
            line="10"
            column="5"/>
    </issue>

    <issue
        id="HardcodedText"
        severity="Warning"
        message="[I18N] Hardcoded string &quot;Email Address&quot;, should use `@string` resource"
        category="Internationalization"
        priority="5"
        summary="Hardcoded text"
        explanation="Hardcoding text attributes directly in layout files is bad for several reasons:

* When creating configuration variations (for example for landscape or portrait)you have to repeat the actual text (and keep it up to date when making changes)

* The application cannot be translated to other languages by just adding new translations for existing string resources.

In Android Studio and Eclipse there are quickfixes to automatically extract this hardcoded string into a resource lookup."
        errorLine1="            android:hint=&quot;Email Address&quot;"
        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
        quickfix="adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/activity_login.xml"
            line="30"
            column="13"/>
    </issue>

    <issue
        id="HardcodedText"
        severity="Warning"
        message="[I18N] Hardcoded string &quot;Password&quot;, should use `@string` resource"
        category="Internationalization"
        priority="5"
        summary="Hardcoded text"
        explanation="Hardcoding text attributes directly in layout files is bad for several reasons:

* When creating configuration variations (for example for landscape or portrait)you have to repeat the actual text (and keep it up to date when making changes)

* The application cannot be translated to other languages by just adding new translations for existing string resources.

In Android Studio and Eclipse there are quickfixes to automatically extract this hardcoded string into a resource lookup."
        errorLine1="            android:hint=&quot;Password&quot;"
        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~"
        quickfix="adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/activity_login.xml"
            line="41"
            column="13"/>
    </issue>

    <issue
        id="HardcodedText"
        severity="Warning"
        message="[I18N] Hardcoded string &quot;SIGN IN&quot;, should use `@string` resource"
        category="Internationalization"
        priority="5"
        summary="Hardcoded text"
        explanation="Hardcoding text attributes directly in layout files is bad for several reasons:

* When creating configuration variations (for example for landscape or portrait)you have to repeat the actual text (and keep it up to date when making changes)

* The application cannot be translated to other languages by just adding new translations for existing string resources.

In Android Studio and Eclipse there are quickfixes to automatically extract this hardcoded string into a resource lookup."
        errorLine1="            android:text=&quot;SIGN IN&quot;"
        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~"
        quickfix="adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/activity_login.xml"
            line="52"
            column="13"/>
    </issue>

    <issue
        id="HardcodedText"
        severity="Warning"
        message="[I18N] Hardcoded string &quot;\?&quot;, should use `@string` resource"
        category="Internationalization"
        priority="5"
        summary="Hardcoded text"
        explanation="Hardcoding text attributes directly in layout files is bad for several reasons:

* When creating configuration variations (for example for landscape or portrait)you have to repeat the actual text (and keep it up to date when making changes)

* The application cannot be translated to other languages by just adding new translations for existing string resources.

In Android Studio and Eclipse there are quickfixes to automatically extract this hardcoded string into a resource lookup."
        errorLine1="            android:text=&quot;\?&quot;"
        errorLine2="            ~~~~~~~~~~~~~~~~~"
        quickfix="adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/widget_service_interval_progress.xml"
            line="27"
            column="13"/>
    </issue>

    <issue
        id="HardcodedText"
        severity="Warning"
        message="[I18N] Hardcoded string &quot;\?&quot;, should use `@string` resource"
        category="Internationalization"
        priority="5"
        summary="Hardcoded text"
        explanation="Hardcoding text attributes directly in layout files is bad for several reasons:

* When creating configuration variations (for example for landscape or portrait)you have to repeat the actual text (and keep it up to date when making changes)

* The application cannot be translated to other languages by just adding new translations for existing string resources.

In Android Studio and Eclipse there are quickfixes to automatically extract this hardcoded string into a resource lookup."
        errorLine1="        android:text=&quot;\?&quot;"
        errorLine2="        ~~~~~~~~~~~~~~~~~"
        quickfix="adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/widget_service_interval_progress.xml"
            line="51"
            column="9"/>
    </issue>

    <issue
        id="HardcodedText"
        severity="Warning"
        message="[I18N] Hardcoded string &quot;\?&quot;, should use `@string` resource"
        category="Internationalization"
        priority="5"
        summary="Hardcoded text"
        explanation="Hardcoding text attributes directly in layout files is bad for several reasons:

* When creating configuration variations (for example for landscape or portrait)you have to repeat the actual text (and keep it up to date when making changes)

* The application cannot be translated to other languages by just adding new translations for existing string resources.

In Android Studio and Eclipse there are quickfixes to automatically extract this hardcoded string into a resource lookup."
        errorLine1="        android:text=&quot;\?&quot;"
        errorLine2="        ~~~~~~~~~~~~~~~~~"
        quickfix="adt">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/widget_service_interval_progress.xml"
            line="61"
            column="9"/>
    </issue>

    <issue
        id="RtlHardcoded"
        severity="Warning"
        message="Consider adding `android:layout_alignParentStart=&quot;true&quot;` to better support right-to-left layouts"
        category="Internationalization:Bidirectional Text"
        priority="5"
        summary="Using left/right instead of start/end attributes"
        explanation="Using `Gravity#LEFT` and `Gravity#RIGHT` can lead to problems when a layout is rendered in locales where text flows from right to left. Use `Gravity#START` and `Gravity#END` instead. Similarly, in XML `gravity` and `layout_gravity` attributes, use `start` rather than `left`.

For XML attributes such as paddingLeft and `layout_marginLeft`, use `paddingStart` and `layout_marginStart`. *NOTE*: If your `minSdkVersion` is less than 17, you should add *both* the older left/right attributes *as well as* the new start/right attributes. On older platforms, where RTL is not supported and the start/right attributes are unknown and therefore ignored, you need the older left/right attributes. There is a separate lint check which catches that type of error.

(Note: For `Gravity#LEFT` and `Gravity#START`, you can use these constants even when targeting older platforms, because the `start` bitmask is a superset of the `left` bitmask. Therefore, you can use `gravity=&quot;start&quot;` rather than `gravity=&quot;left|start&quot;`.)"
        errorLine1="        android:layout_alignParentLeft=&quot;true&quot;"
        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/widget_service_interval_progress.xml"
            line="48"
            column="9"/>
    </issue>

    <issue
        id="RtlHardcoded"
        severity="Warning"
        message="Consider adding `android:layout_alignParentEnd=&quot;true&quot;` to better support right-to-left layouts"
        category="Internationalization:Bidirectional Text"
        priority="5"
        summary="Using left/right instead of start/end attributes"
        explanation="Using `Gravity#LEFT` and `Gravity#RIGHT` can lead to problems when a layout is rendered in locales where text flows from right to left. Use `Gravity#START` and `Gravity#END` instead. Similarly, in XML `gravity` and `layout_gravity` attributes, use `start` rather than `left`.

For XML attributes such as paddingLeft and `layout_marginLeft`, use `paddingStart` and `layout_marginStart`. *NOTE*: If your `minSdkVersion` is less than 17, you should add *both* the older left/right attributes *as well as* the new start/right attributes. On older platforms, where RTL is not supported and the start/right attributes are unknown and therefore ignored, you need the older left/right attributes. There is a separate lint check which catches that type of error.

(Note: For `Gravity#LEFT` and `Gravity#START`, you can use these constants even when targeting older platforms, because the `start` bitmask is a superset of the `left` bitmask. Therefore, you can use `gravity=&quot;start&quot;` rather than `gravity=&quot;left|start&quot;`.)"
        errorLine1="        android:layout_alignParentRight=&quot;true&quot;"
        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
        <location
            file="/Users/stkent/dev/detroit_labs/apps/redacted/app/src/main/res/layout/widget_service_interval_progress.xml"
            line="58"
            column="9"/>
    </issue>

</issues>
@stkent stkent added the bug label Jun 23, 2016
@stkent stkent self-assigned this Jun 23, 2016
@stkent
Copy link
Collaborator Author

stkent commented Jun 23, 2016

This is a logged exception that probably doesn't need to be shown to end users in its entirety.

Currently, we attempt to parse a line number that may or may not be present. If it is, parsing (should) succeed. If it is not, parsing is expected to fail. Printing an "error" message and showing the full stack trace to end users is alarmist!

@stkent
Copy link
Collaborator Author

stkent commented Jun 23, 2016

@btkelly how do you feel about replacing

        xml.issue.findAll { severityEnabled((String) it.@severity.text()) }
                .each { violation ->
                        final Integer lineNumber;

                        try {
                            lineNumber = violation.location.@line.toInteger()
                        } catch (final NumberFormatException e) {
                            System.out.println("Error reading line number from Android Lint violations.");
                            e.printStackTrace();
                            lineNumber = null
                        }

                        result.add(new Violation(
                                sanitize((String) violation.@id.text()),
                                sanitize((String) name()),
                                sanitize((String) violation.@message.text()),
                                sanitize((String) violation.@url.text()),
                                sanitize((String) violation.location.@file.text())
                                        .replace(project.rootDir.absolutePath + "/", ""),

                                lineNumber))
                }

with something like

        xml.issue.findAll { severityEnabled((String) it.@severity.text()) }
                .each { violation ->
                        final String violationName = sanitize((String) violation.@id.text())

                        final String lineNumberString = sanitize((String) violation.location.@line.text())
                        final Integer lineNumber;

                        if (lineNumberString.isEmpty()) {
                            lineNumber = null
                        } else {
                            try {
                                lineNumber = lineNumberString.toInteger()
                            } catch (final NumberFormatException ignored) {
                                System.out.println(
                                        "Error parsing line number string: " + lineNumberString +
                                             " for Android Lint violation: " + violationName);

                                lineNumber = null
                            }
                        }

                        result.add(new Violation(
                                violationName,
                                sanitize((String) name()),
                                sanitize((String) violation.@message.text()),
                                sanitize((String) violation.@url.text()),
                                sanitize((String) violation.location.@file.text())
                                        .replace(project.rootDir.absolutePath + "/", ""),

                                lineNumber))
                }

@stkent
Copy link
Collaborator Author

stkent commented Jun 23, 2016

That parsing logic could then be pulled into a default method pretty easily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant