forked from xamarin/jar2xml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
310 lines (227 loc) · 11.4 KB
/
README
1
2
3
4
5
6
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
jar2xml is a tool to extract API information from a java archive
and associated documentation. The information is stored in XML format.
* Prerequisites
- mono (to run build tools)
- xmllint (for doc scraping)
- xmlstarlet (ditto)
Also it uses ASM (included in the sources)
* Tools
- jar2xml : the main converter to generate the primary target xmls.
- scraper.exe : annotation doc scraper to generate annotations/*.xml.
scraper-*.sh : shells used for scraper input. They are piped.
* <del>Easy</del> comparison
There are two levels of comparisons.
DLL: gui-compare in mono-tools is your friend. Compare new one against
old assembly of the corresponding API profile.
XML: It is now implemented as "make test-8" as well as "make test-13"
See Makefile for details. Things are not really simple to explain shortly.
$ java -jar jar2xml.jar --jar=/home/atsushi/android-sdk-linux_x86/platforms/android-8/android.jar --out=_8.xml --docpath=/home/atsushi/android-sdk-linux_x86/docs/reference
$ mono-xmltool --prettyprint 8.xml > 8_.xml
$ xmlstarlet c14n 8_.xml > 8.xml
$ mono-xmltool --prettyprint _8.xml > _8_.xml
$ xmlstarlet c14n _8_.xml > _8.xml
$ diff -u 8.xml _8.xml
* Difference from AOSP API XML
- Type parameters on Class and Method are now explicitly written as:
<typeParameters> <!-- if any -->
<typeParameter name="...">
<genericConstraints> <!-- if any -->
<genericConstraint type="..."></genericConstraint>
</genericConstraints>
</typeParameter>
</typeParameters>
see e.g. android.accounts.AccountManagerCallback<V>
There are some cases that we dare output type parameters embedded
into type name (basically those in XML attributes):
- genericConstraint/@type (see above)
- exception/@type (it would hardly happen though)
These are temporarily disabled and will be back when we really move
to the new generic design.
- class/@extends
- implements/@name
- field/@type
* TODO
** Postponed
- java.security.Provider.put() : missing in jar2xml output.
Disappeared in the shade of Hashtable.put().
-> workarounded by explicitly excluding the case (hardcoded in jar2xml!)
This issue should rather get fixed by improving overrload resolution
in XML level i.e. change XML format to include *any* overloaded methods
that AOSP XML does not do.
- java.net.ssl.KeyStoreBuilderParameters.Parameters and .ctor() : types differ
- generic list
- Now there are some abstract methods that somehow lacked in AOSP XML
and it uncovered issues regarding overriden methods. While those overriden
methods are sometimes "final", which should be "sealed", they are not
marked as sealed. And we cannot mark them as sealed right now since
those methods are *overriden* in *Invoker classes.
e.g. java.nio.Buffer.arrayOffset() and those overriden methods in *Buffer.
- android.hardware.SensorManager.GRAVITY_DEATH_STAR_I always returns 0
- while reference and AOSP indicates value, it returns 0 on reflection,
asm or even on ASUS Transformer.
- android.test.MoreAsserts.assertEquals(Set<?>, Set<?>).
They are just XML difference between <?> (wrong) and <? extends Object>
(correct), which affected doc scraping for parameter name retrieval.
- java.util.Calendar AllStyles, Long and Short are now properties, but
they should be actually enums. The thing is, they are *missing* in AOSP
XML so they had weren't converted to enums by our generator stuff.
- android.util.Pair : ThresholdClass and ThreasholdType are extraneous.
They are not in jar2xml output either, maybe added by api fixup stage.
(First and Second are looking as extra, but they were rather missing)
** things changes are maybe preferred
*** int->enum
- Android.App.DownloadManager
- Android.Appwidget.AppWidgetManager
- Android.Bluetooth.BluetoothA2dp
- Android.Bluetooth.BluetoothHeadset
- Android.Content.PM.PackageManager
- Android.Content.Res.Configuration
- Android.Database.Sqlite.SQLiteDatabase
- Android.Graphics.PowerDuff.Mode
- Android.Media.AudioManager.ScoAudioState*
- Android.OS.BatteryManager
- Android.Views.InputDevice
- Android.Views.View.Measured*
- Android.Views.Window.Progress*
- Android.Views.Window.WindowManagerLayoutParams
- Android.Views.View.SystemUiVisibilityChangeEventArgs has int Visibility
which should be StatusBarVisibility.
- Android.Widget.OnScrollListenerConsts
*** methods->properties
- Android.App.Admin.DevicePolicyManager: there are lots of GetPassword*() and
SetPassword*() methods which we might be able to change to indexers.
* Notes (that you don't have to read)
** API difference between android.jar and J2SE
These API differences could be problematic when we reflect java system types (reflection limitation).
- javax.net.ssl.ServerSocketFactory.getDefault() is synchronized in android
and not in J2SE.
-> in jar2xml, it is manually fixed.
** AOSP XML issues
Lots of missing pieces:
http://code.google.com/p/android/issues/detail?id=19569
** Notes on Annotations
Annotation such as java.lang.Deprecated do not seem to exist
in android.jar. That includes, types themselves.
java.lang.annotation types suffer from this.
I find it almost desparate and the only solution I couold think of was
to build AOSP android.jar or some equivalence that does *not* strip
those annotations off, *for each platform version*.
That sounds so time-eater.
The AOSP API document is generated as out/target/common/obj/PACKAGING/android_jar_intermediaries/public_api.xml (at that state there still must be annotations, or this xml should not contain annotation information at all).
Also,
out/target/common/obj/JAVA_LIBRARIES/framework_intermediaries and
out/target/common/obj/JAVA_LIBRARIES/core_intermediaries
contains debug jars that still seem to hold annotations.
development/tools/apkcheck/README.txt might be of interest too.
This is from the latest AOSP build (as of Aug.17, 2011). I'm not sure
if this applies to older versions.
On the other hand, I noticed that Annotation types are very easy to fill;
they have almost fixed members (from java.lang.Object). So I rather
think they can be manually filled (or if we want to be puritan, scrape
"Known Indirect Subclasses" from java/lang/annotation/Annotation.html).
Annotations are:
android.test.FlakyTest
android.test.UiThreadTest
android.test.suitebuilder.annotation.LargeTest
android.test.suitebuilder.annotation.MediumTest
android.test.suitebuilder.annotation.SmallTest
android.test.suitebuilder.annotation.Smoke
android.test.suitebuilder.annotation.Suppress
android.view.ViewDebug$CapturedViewProperty
android.view.ViewDebug$ExportedProperty
android.view.ViewDebug$FlagToString
android.view.ViewDebug$IntToString
android.widget.RemoteViews$RemoteView
dalvik.annotation.TestTarget
dalvik.annotation.TestTargetClass
java.lang.Deprecated
java.lang.Override
java.lang.SuppressWarnings
java.lang.annotation.Documented
java.lang.annotation.Inherited
java.lang.annotation.Retention
java.lang.annotation.Target
java.lang.annotation.Documented
** Old Notes on Annotations
Current implementation uses java.lang.reflect API to get member
annotations, but it won't work as expected.
I found that .class files in android.jar are stripped off field
annotations. For example, java.net.HttpURLConnection#HTTP_SERVER_ERROR
should be annotated with @Deprecated, but it isn't.
On the other hand, class annotations are alive.
(e.g. java/security/Certificate.class)
I guess is that AOSP uses proguard which strips member annotations.
The reason why we can somehow retrieve @Deprecated on
HttpURLConnection#HTTP_SERVER_ERROR by jar2xml is likely that
URLClassLoader.getClass() actually does not load java.* classes from
the jar contents but just returns the runtime one (such as openjdk).
Javassist.Loader javadoc explains its limitation on loading java.*
/ javax.* classes. [*1]
(So, it is not even about "runtime visible/invisible annotations".
I tried to read android.jar classes using ASM ClassReader [*2] and
it couldn't find any annotations on FieldNode (and from what I read
from asm sources, I believe it is by no means bug in ASM).
I have added separate doc scraper, which uses xmllint (to xmlize html docs)
and xmlstarlet (for convenient XPath query). Run "make annotations/13.xml"
for instance (should be available to all versions, I'm just lazy to hack
makefiles before confirming that it's all good).
[*1] http://www.csg.is.titech.ac.jp/~chiba/javassist/html/javassist/Loader.html
[*2] http://asm.ow2.org/asm33/javadoc/user/org/objectweb/asm/ClassReader.html
** Notes on per-version doc scraping
We used to scrape only reference for the latest API which was problematic.
Now we have version-aware scraper and resolved the issue described below.
<historical>
Doc scraper still misses some parameter names
e.g. android.text.method.ScrollingMovementMethod.onKeyUp()
This matters when api-fixup is involved (it matches nodes by parameter
names and then it dismisses the target nodes!).
Actually this is not going to be very good; there are some methods
that are removed in the latest API (the example method above is exactly
the case). We'll have to sort out some alternative approach.
A possible approach is to checkout API docs for *every* version (from
AOSP).
</historical>
** Byte code engineering
Now we use ASM to solve the issues below:
<historical>
- Some fields were incorrectly marked as constant. For example,
android.os.Build.TIME is not a constant, but since the field.getLong()
returns 0, it is set as 0 (and it does not return null for get()).
java.io.File.pathSeparatorChar has the same problem, but it is worse;
it returns non-zero value so we cannot depend on the value.
Solution ideas: scrape constant values, or use ASM.
- Constant values for "protected" fields need to be retrieved, but Java reflection API throws IllegalAccessException for such attempt.
This likely has to be resolved by bytecode engineering (such as ASM).
</historical>
** Issues regarding stripped non-public class (resolved)
<maybe-historical>
- java.lang.AbstractStringBuilder exposes an issue that
interface members on non-public types are returned by
class#getDeclaredMethods() while they are *not* declared.
Those methods (or those AbstractStringBuilder methods) are excluded by
checking special modifier 0x1000 (4096).
Also this involves check for derived methods (many overriden methods are
excluded, but this brings another check to *not* exclude methods when
the corresponding base methods are excluded).
</maybe-historical>
** Method override resolution
<maybe-historical>
- Do not skip certain overriden methods. This in JavaClass.java gives
equivalent output to AOSP xml, but it's not good:
if (base_method != null) {
int base_mods = base_method.getModifiers ();
if (!Modifier.isAbstract (base_mods) && (Modifier.isPublic (mmods) == Modifier.isPublic (base_mods)))
continue;
}
This causes GridView.setAdapter() ignored and thus fails to generate
valid property. It hides overriden methods.
I simply commented out, then a bunch of hidden overriden methods
appeared. And since we don't handle int->enum conversions on those
methods, they simply fail to compile. Maybe fixing above to match
existing format is a good-enough compromization.
Another notable thing is that AbsListView.setAdapter() does not
exist in api-4.xml. It is likely because abstract methods are
ignored (it is abstract, though that fact does not appear on
android javadoc).
android.view.MotionEvent.getSource() is also missing.
</maybe-historical>