Utility for checking API compatibility with JDK

Stuart Ballard kaffe@rufus.w3.org
Mon, 12 Jun 2000 11:20:20 -0400


This is a multi-part message in MIME format.
--------------8A84F3000079C87690518845
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,

I'm attaching a Java program and perl script I wrote to test
compatibility between the JDK and free versions. It's in its early
stages but from my testing so far, the results are already interesting.
Consider both the attached files to be under the GPL (sorry about the
lack of legal headers).

WARNING:
IANAL and I don't know the legal implications of this program. I don't
know of any reason why it shouldn't be legitimate for any free program
to use; when running under the JDK it only uses public APIs and only
extracts information that's in the public documentation anyway. But I
suggest waiting until there's some sort of consensus on whether this is
legitimate for your project before potentially contaminating yourself by
finding out the results.

USAGE:
To use the program (I'll tack on -jdk or -free to command names so you
know which one I mean. "-free" is obviously kaffe or japhar or whatever
implementation you are testing).

$ java-jdk11 net.wuffies.japi.Japize -f $JAVAHOME/lib/classes.zip java >
jdk11.japi
$ grep -v '^java\.awt\.peer' jdk11.japi | grep -v
'^java\.text\.resources' > jdk11real.japi
[These are public packages in the java hierarchy but aren't in the
documented API]
$ java-free net.wuffies.japi.Japize -f $FREEHOME/Klasses.jar java >
free.japi
[If you're using kaffe, also do
$ java-free net.wuffies.japi.Japize -f $FREEHOME/rmi.jar java >>
free.japi
]
$ japicompat.pl jdk11real.japi free.japi

Note that this program doesn't do "symmetric" testing, but rather tests
for "backward compatibility". It's approximately checking for a "subset"
relation. Since most free implementations lie somewhere between jdk1.1
and jdk1.2, the "interesting" questions to ask are:

japicompat.pl jdk11.japi free.japi
japicompat.pl free.japi jdk12.japi

Of course, to see how well Sun kept to their own rules for backward
compatibility...
japicompat.pl jdk11.japi jdk12.japi
is also kind of interesting. I haven't tried this yet.

So far, I've only tested on kaffe against jdk11. There's a workaround in
the code for the bug that I recently posted on the kaffe list; every
time that workaround is needed, a "!" or an "M" appear on stderr (I
don't know why the "M"s ever happen... this may be another bug. See the
code).

I'll post my results if there's a consensus that it's legal to do so.

BUGS:
I'm sure there are lots. The commenting stinks, for a start; I'll try to
improve this over the next couple of days. Also, I need to go over the
details of "Binary compatibility" as defined in the JLS to make sure
that I'm testing for exactly everything I should be. One known issue is
that the figuring out of what interfaces a class supports is limited to
checking the class itself rather than its superclasses; I have a fix for
that mostly written but not integrated.

NOTES:
I haven't ever succeeded in getting Japhar+classpath to actually run, so
this is 100% untested on that combination. It requires basic
functionality from java.util.zip, which I'm not sure is fully integrated
into classpath yet; you may need to add this by hand.

Although it takes a jar file as an argument, it doesn't actually load
classes from that jar; it just looks at the filenames, trims off the
".class", substitutes "." for "/" and then uses Class.forName(). I
didn't use an URLClassLoader because I needed to run it on 1.1.

Although Japize itself can't run on 1.0, it might be possible to use a
perl script on the results of javap to get a jdk10.japi file. I'm not
particularly interested in doing this in the short term; 1.0
compatibility is more-or-less irrelevant these days. The only interest
this would hold would be to compare jdk10.japi with jdk11.japi...

Depending on the consensus of legality, this might be interesting to
include into Mauve. I haven't cc'd that list because I'm not on it.

Have fun with this; patches are welcome :)

Stuart.
--------------8A84F3000079C87690518845
Content-Type: application/octet-stream;
 name="japicompat.pl"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="japicompat.pl"

IyEvdXNyL2Jpbi9wZXJsCgojIFBhcnNlIGNtZGxpbmUgYW5kIGdpdmUgYSB1c2FnZSBtZXNz
YWdlLgpteSAoJG9yaWdmaWxlLCAkbmV3ZmlsZSkgPSBAQVJHVjsKaWYgKCFkZWZpbmVkICRu
ZXdmaWxlKSB7CiAgcHJpbnQgIlVzYWdlOiBqYXBpY29tcGF0LnBsIDxvcmlnaW5hbCBhcGk+
IDxhcGkgdG8gY2hlY2s+XG4iOwogIGV4aXQgMTsKfQoKIyBSZWFkIHRoZSAibmV3IiBBUEkg
YW5kIHN0b3JlIGFsbCB0aGUgZGV0YWlscyBpbiBvbmUgZ2lhbnQgaGFzaHJlZiwgJG5ldy4g
VGhlCiMgIm5ldyIgb25lIGlzIHBhcnNlZCBmaXJzdCBiZWNhdXNlIHdlIG5lZWQgdG8gY2hl
Y2sgdGhhdCBhbiBlbnRyeSBleGlzdHMgaW4gbmV3CiMgZm9yIGV2ZXJ5IGVudHJ5IGluIG9y
aWcuCm9wZW4gSU4sICRuZXdmaWxlIG9yIGRpZSAiQ291bGQgbm90IG9wZW4gJG5ld2ZpbGUi
Owp3aGlsZSAoPElOPikgewogIGNob21wOwoKICAjIFBhcnNlIGFuZCBpbnRlcnByZXQgdGhl
IGVudHJ5LgogIG15ICgkaXRlbSwgJGFjY2VzcywgJGFic3RyYWN0LCAkc3RhdGljLCAkZmlu
YWwsICR0eXBlKSA9IHNwbGl0IC8gLywgJF8sIDY7CiAgbXkgKCRjbGFzcywgJG1lbWJlcikg
PSBzcGxpdCAvIy8sICRpdGVtLCAyOwogIG15ICRpc2E7CiAgaWYgKCRtZW1iZXIgZXEgIiIp
IHsKICAgICRpc2EgPSAkdHlwZSA9fiAvY2xhc3MvID8gImNsYXNzIiA6ICJpbnRlcmZhY2Ui
OwogIH0gZWxzaWYgKCRtZW1iZXIgPX4gL15cKC4qXCkkLykgewogICAgJGlzYSA9ICJjb25z
dHJ1Y3RvciI7CiAgfSBlbHNpZiAoJG1lbWJlciA9fiAvXCguKlwpJC8pIHsKICAgICRpc2Eg
PSAibWV0aG9kIjsKICB9IGVsc2UgewogICAgJGlzYSA9ICJmaWVsZCI7CiAgfQoKICAjIFN0
b3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlbnRyeSBpbiAkbmV3LT57JGl0ZW19LgogICRu
ZXctPnskaXRlbX0tPntpc2F9ID0gJGlzYTsKICAkbmV3LT57JGl0ZW19LT57Y2xhc3N9ID0g
JGNsYXNzOwogICRuZXctPnskaXRlbX0tPnttZW1iZXJ9ID0gJG1lbWJlcjsKICAkbmV3LT57
JGl0ZW19LT57YWNjZXNzfSA9ICRhY2Nlc3M7CiAgJG5ldy0+eyRpdGVtfS0+e2Fic3RyYWN0
fSA9ICRhYnN0cmFjdDsKICAkbmV3LT57JGl0ZW19LT57c3RhdGljfSA9ICRzdGF0aWM7CiAg
JG5ldy0+eyRpdGVtfS0+e2ZpbmFsfSA9ICRmaW5hbDsKCiAgIyBDbGFzc2VzIGFuZCBpbnRl
cmZhY2VzIGhhdmUgc3VwZXJjbGFzc2VzIGFuZCBpbXBsZW1lbnRlZCBpbnRlcmZhY2VzIHRh
Y2tlZAogICMgb24gdG8gdGhlICJ0eXBlIiBmaWVsZC4gV2Ugc3RvcmUgdGhpcyBpbmZvcm1h
dGlvbiBpbiB0aGUgJG5ldyBoYXNoIGFsc28uCiAgaWYgKCRtZW1iZXIgZXEgIiIpIHsKCiAg
ICAjIEdldCB0aGUgaW50ZXJmYWNlcyBkYXRhLCB3aGljaCBpcyBzZXBhcmF0ZWQgYnkgJyon
cyBmcm9tIHRoZSBjbGFzc25hbWUuCiAgICBteSBAaWZhY2VzID0gc3BsaXQoL1wqLywgJHR5
cGUpOwogICAgJHR5cGUgPSBzaGlmdCBAaWZhY2VzOwogICAgZm9yZWFjaCBteSAkaWZhY2Ug
KEBpZmFjZXMpIHsKICAgICAgJG5ldy0+eyRpdGVtfS0+e2lmYWNlc30tPnskaWZhY2V9ID0g
MTsKICAgIH0KCiAgICAjIEdldCB0aGUgY2xhc3MncyBzdXBlcmNsYXNzZXMsIHdoaWNoIGFy
ZSBzZXBhcmF0ZWQgYnkgJzoncy4KICAgIG15IEBzdXBlcnMgPSBzcGxpdCgvOi8sICR0eXBl
KTsKICAgICR0eXBlID0gc2hpZnQgQHN1cGVyczsKICAgIGZvcmVhY2ggbXkgJHN1cGVyIChA
c3VwZXJzKSB7CiAgICAgICRuZXctPnskaXRlbX0tPntzdXBlcnN9LT57JHN1cGVyfSA9IDE7
CiAgICB9CgogICMgTWV0aG9kcyBhbmQgY29uc3RydWN0b3JzIGhhdmUgZXhjZXB0aW9ucyB0
aGF0IGNhbiBiZSB0aHJvd24gc2VwYXJhdGVkIGJ5CiAgIyAnKidzIGZyb20gdGhlIHR5cGVu
YW1lLiBUaGVzZSBhbHNvIG5lZWQgdG8gZ2V0IHN0b3JlZCBpbiB0aGUgJG5ldyBoYXNoLgog
IH0gZWxzaWYgKCRtZW1iZXIgPX4gL1woLipcKSQvKSB7CiAgICBteSBAZXhjcHMgPSBzcGxp
dCgvXCovLCAkdHlwZSk7CiAgICAkdHlwZSA9IHNoaWZ0IEBleGNwczsKICAgIGZvcmVhY2gg
bXkgJGV4Y3AgKEBleGNwcykgewogICAgICAkbmV3LT57JGl0ZW19LT57ZXhjcHN9LT57JGV4
Y3B9ID0gMTsKICAgIH0KICB9CgogICMgU3RvcmUgd2hhdCdzIGxlZnQgb2YgdGhlIHR5cGUg
YWZ0ZXIgcGFyc2luZyBvZmYgYWxsIG9mIHRob3NlIHBhcnRzLgogICRuZXctPnskaXRlbX0t
Pnt0eXBlfSA9ICR0eXBlOwp9CmNsb3NlIElOOwoKIyBGSVhNRTogQWxsIG9mIHRoaXMgYmln
IHNlY3Rpb24sIHdoZXJlIHRoZSBoYXJkIHdvcmsgaXMgZG9uZSwgbmVlZHMgY29tbWVudGlu
Zy4Kb3BlbiBJTiwgJG9yaWdmaWxlIG9yIGRpZSAiQ291bGQgbm90IG9wZW4gJG9yaWdmaWxl
IjsKJGVycnM9MDsgJW1pc3Npbmc9KCk7ICViYWQ9KCk7ICVnb29kPSgpOwp3aGlsZSAoPElO
PikgewogIGNob21wOwogIG15ICgkaXRlbSwgJGFjY2VzcywgJGFic3RyYWN0LCAkc3RhdGlj
LCAkZmluYWwsICR0eXBlKSA9IHNwbGl0IC8gLywgJF8sIDY7CiAgbXkgKCRjbGFzcywgJG1l
bWJlcikgPSBzcGxpdCAvIy8sICRpdGVtLCAyOwogIG15ICRpc2E7CiAgaWYgKCRtZW1iZXIg
ZXEgIiIpIHsKICAgICRpc2EgPSAkdHlwZSA9fiAvY2xhc3MvID8gImNsYXNzIiA6ICJpbnRl
cmZhY2UiOwogIH0gZWxzaWYgKCRtZW1iZXIgPX4gL15cKC4qXCkkLykgewogICAgJGlzYSA9
ICJjb25zdHJ1Y3RvciI7CiAgfSBlbHNpZiAoJG1lbWJlciA9fiAvXCguKlwpJC8pIHsKICAg
ICRpc2EgPSAibWV0aG9kIjsKICB9IGVsc2UgewogICAgJGlzYSA9ICJmaWVsZCI7CiAgfQog
ICRuaXRlbSA9ICRuZXctPnskaXRlbX07CiAgJGVycmhlcmUgPSAwOwogIHVubGVzcyAoZGVm
aW5lZCgkbml0ZW0pKSB7CiAgICB1bmxlc3MgKCRtaXNzY2xhc3MtPnskY2xhc3N9KSB7CiAg
ICAgIHByaW50ICIkaXNhICRpdGVtIG5vdCBkZWZpbmVkIGluICRuZXdmaWxlXG4iOwogICAg
ICAkZXJycysrOyAkbWlzc2luZ3skaXNhfSsrOwogICAgfQogICAgaWYgKCRtZW1iZXIgZXEg
IiIpIHsKICAgICAgJG1pc3NjbGFzcy0+eyRjbGFzc30gPSAxOwogICAgfQogICAgbmV4dDsK
ICB9CiAgaWYgKCRhY2Nlc3MgZXEgInB1YmxpYyIgJiYgJG5pdGVtLT57YWNjZXNzfSBuZSAi
cHVibGljIikgewogICAgcHJpbnQgIiRpc2EgJGl0ZW0gaXMgcHVibGljIGluICRvcmlnZmls
ZSBidXQgcHJvdGVjdGVkIGluICRuZXdmaWxlXG4iOwogICAgJGVycnMrKzsgJGVycmhlcmUr
KzsKICB9CiAgaWYgKCRhYnN0cmFjdCBlcSAiY29uY3JldGUiICYmICRuaXRlbS0+e2Fic3Ry
YWN0fSBuZSAiY29uY3JldGUiKSB7CiAgICBwcmludCAiJGlzYSAkaXRlbSBpcyBjb25jcmV0
ZSBpbiAkb3JpZ2ZpbGUgYnV0IGFic3RyYWN0IGluICRuZXdmaWxlXG4iOwogICAgJGVycnMr
KzsgJGVycmhlcmUrKzsKICB9CiAgaWYgKCRzdGF0aWMgbmUgJG5pdGVtLT57c3RhdGljfSkg
ewogICAgcHJpbnQgIiRpc2EgJGl0ZW0gaXMgJHN0YXRpYyBpbiAkb3JpZ2ZpbGUgYnV0ICRu
aXRlbS0+e3N0YXRpY30gaW4gJG5ld2ZpbGVcbiI7CiAgICAkZXJycysrOyAkZXJyaGVyZSsr
OwogIH0KICBpZiAoJGZpbmFsIGVxICJub25maW5hbCIgJiYgJG5pdGVtLT57ZmluYWx9IG5l
ICJub25maW5hbCIpIHsKICAgIHByaW50ICIkaXNhICRpdGVtIGlzIG5vbmZpbmFsIGluICRv
cmlnZmlsZSBidXQgZmluYWwgaW4gJG5ld2ZpbGVcbiI7CiAgICAkZXJycysrOyAkZXJyaGVy
ZSsrOwogIH0KICBpZiAoJG1lbWJlciBlcSAiIikgewogICAgbXkgQGlmYWNlcyA9IHNwbGl0
KC9cKi8sICR0eXBlKTsKICAgICR0eXBlID0gc2hpZnQgQGlmYWNlczsKICAgIGZvcmVhY2gg
bXkgJGlmYWNlIChAaWZhY2VzKSB7CiAgICAgIHVubGVzcyAoJG5pdGVtLT57aWZhY2VzfS0+
eyRpZmFjZX0pIHsKICAgICAgICBwcmludCAiJGlzYSAkaXRlbSBpbXBsZW1lbnRzICRpZmFj
ZSBpbiAkb3JpZ2ZpbGUgYnV0IG5vdCBpbiAkbmV3ZmlsZVxuIjsKICAgICAgICAkZXJycysr
OyAkZXJyaGVyZSsrOwogICAgICB9CiAgICB9CiAgICBteSBAc3VwZXJzID0gc3BsaXQoLzov
LCAkdHlwZSk7CiAgICAkdHlwZSA9IHNoaWZ0IEBzdXBlcnM7CiAgICBteSAkc3VwZXIgPSBz
aGlmdCBAc3VwZXJzOwogICAgaWYgKGRlZmluZWQgJHN1cGVyIGFuZCAhJG5pdGVtLT57c3Vw
ZXJzfS0+eyRzdXBlcn0pIHsKICAgICAgcHJpbnQgIiRpc2EgJHtpdGVtfSdzIHN1cGVyY2xh
c3MgJHN1cGVyIGluICRvcmlnZmlsZSBpcyBub3QgaXRzIHN1cGVyY2xhc3MgaW4gJG5ld2Zp
bGVcbiI7CiAgICAgICRlcnJzKys7ICRlcnJoZXJlKys7CiAgICB9CiAgfSBlbHNpZiAoJG1l
bWJlciA9fiAvXCguKlwpLykgewogICAgbXkgQGV4Y3BzID0gc3BsaXQoL1wqLywgJHR5cGUp
OwogICAgbXkgJGV4Y3BzID0ge307CiAgICAkdHlwZSA9IHNoaWZ0IEBleGNwczsKICAgIGZv
cmVhY2ggbXkgJGV4Y3AgKEBleGNwcykgewogICAgICB1bmxlc3MgKCRuaXRlbS0+e2V4Y3Bz
fS0+eyRleGNwfSkgewogICAgICAgIHByaW50ICIkaXNhICRpdGVtIHRocm93cyAkZXhjcCBp
biAkb3JpZ2ZpbGUgYnV0IG5vdCBpbiAkbmV3ZmlsZVxuIjsKICAgICAgICAkZXJycysrOyAk
ZXJyaGVyZSsrOwogICAgICB9CiAgICAgICRleGNwcy0+eyRleGNwfSA9IDE7CiAgICB9CiAg
ICBmb3JlYWNoIG15ICRleGNwIChrZXlzICV7JG5pdGVtLT57ZXhwc319KSB7CiAgICAgIHVu
bGVzcyAoJGV4Y3BzLT57JGV4Y3B9KSB7CiAgICAgICAgcHJpbnQgIiRpc2EgJGl0ZW0gdGhy
b3dzICRleGNwIGluICRuZXdmaWxlIGJ1dCBub3QgaW4gJG9yaWdmaWxlXG4iOwogICAgICAg
ICRlcnJzKys7ICRlcnJoZXJlKys7CiAgICAgIH0KICAgIH0KICB9CiAgaWYgKCR0eXBlIG5l
ICRuaXRlbS0+e3R5cGV9KSB7CiAgICBwcmludCAiJGlzYSAke2l0ZW19J3MgdHlwZSBkb2Vz
IG5vdCBtYXRjaCBiZXR3ZWVuICRvcmlnZmlsZSBbJHR5cGVdIGFuZCAkbmV3ZmlsZSBbJG5p
dGVtLT57dHlwZX1dXG4iOwogICAgJGVycnMrKzsgJGVycmhlcmUrKzsKICB9CiAgaWYgKCRl
cnJoZXJlKSB7CiAgICAkYmFkeyRpc2F9Kys7CiAgfSBlbHNlIHsKICAgICRnb29keyRpc2F9
Kys7CiAgfQp9CgojIFByaW50IHN1bW1hcnkgaW5mb3JtYXRpb24uCnByaW50IDw8RU9GCkNs
YXNzZXM6ICRtaXNzaW5ne2NsYXNzfSBtaXNzaW5nLCAkYmFke2NsYXNzfSBiYWQsICRnb29k
e2NsYXNzfSBnb29kLgpJbnRlcmZhY2VzOiAkbWlzc2luZ3tpbnRlcmZhY2V9IG1pc3Npbmcs
ICRiYWR7aW50ZXJmYWNlfSBiYWQsICRnb29ke2ludGVyZmFjZX0gZ29vZC4KRmllbGRzOiAk
bWlzc2luZ3tmaWVsZH0gbWlzc2luZywgJGJhZHtmaWVsZH0gYmFkLCAkZ29vZHtmaWVsZH0g
Z29vZC4KQ29uc3RydWN0b3JzOiAkbWlzc2luZ3tjb25zdHJ1Y3Rvcn0gbWlzc2luZywgJGJh
ZHtjb25zdHJ1Y3Rvcn0gYmFkLCAkZ29vZHtjb25zdHJ1Y3Rvcn0gZ29vZC4KTWV0aG9kczog
JG1pc3Npbmd7bWV0aG9kfSBtaXNzaW5nLCAkYmFke21ldGhvZH0gYmFkLCAkZ29vZHttZXRo
b2R9IGdvb2QuClRvdGFsIEVycm9zOiAkZXJycy4KRU9GCg==
--------------8A84F3000079C87690518845
Content-Type: application/octet-stream;
 name="Japize.java"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="Japize.java"

cGFja2FnZSBuZXQud3VmZmllcy5qYXBpOwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuKjsK
aW1wb3J0IGphdmEudXRpbC56aXAuKjsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Cmlt
cG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CgovKioKICogUHJvY2VzcyBhIEphdmEgQVBJ
IGFuZCBlbWl0IGEgbWFjaGluZS1yZWFkYWJsZSBkZXNjcmlwdGlvbiBvZiB0aGUgQVBJLAog
KiBzdWl0YWJsZSBmb3IgY29tcGFyaXNvbiB0byBvdGhlciBBUElzLiBTcGVjaWZpY2FsbHks
IHRoZSBwZXJsIHNjcmlwdAogKiBqYXBpY29tcGF0LnBsIGNhbiB0ZXN0IEFQSXMgZm9yIHNv
dXJjZS9iaW5hcnkgY29tcGF0aWJpbGl0eSB3aXRoIGVhY2ggb3RoZXIuCiAqCiAqIEBhdXRo
b3IgU3R1YXJ0IEJhbGxhcmQgJmx0OzxhIGhyZWY9Im1haWx0bzpzYmFsbGFyZEB3dWZmaWVz
Lm5ldCI+c2JhbGxhcmRAd3VmZmllcy5uZXQ8L2E+Jmd0OwogKi8KcHVibGljIGNsYXNzIEph
cGl6ZSB7CgogIC8qKgogICAqIFBhcnNlIHRoZSBwcm9ncmFtJ3MgYXJndW1lbnRzIGFuZCBw
ZXJmb3JtIHRoZSBtYWluIHByb2Nlc3NpbmcuCiAgICovCiAgcHVibGljIHN0YXRpYyB2b2lk
IG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sIElP
RXhjZXB0aW9uLCBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKICAgIGlmIChhcmdzLmxlbmd0
aCA9PSAwKSB7CiAgICAgIFN5c3RlbS5lcnIucHJpbnRsbigiVXNhZ2U6IEphcGl6ZSBbLWMg
Y2xhc3NuYW1lIC4uLiB8IC1mIHppcGZpbGUgcGFja2FnZSAuLi5dID5vdXRwdXQuamFwaSIp
OwogICAgfSBlbHNlIGlmICgiLWMiLmVxdWFscyhhcmdzWzBdKSkgewogICAgICBmb3IgKGlu
dCBpID0gMTsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBqYXBpemVDbGFzcyhh
cmdzW2ldKTsKICAgICAgfQogICAgfSBlbHNlIGlmICgiLWYiLmVxdWFscyhhcmdzWzBdKSAm
JiBhcmdzLmxlbmd0aCA+IDIpIHsKICAgICAgZm9yIChpbnQgaSA9IDI7IGkgPCBhcmdzLmxl
bmd0aDsgaSsrKSB7CiAgICAgICAgcHJvY2Vzc1ppcChhcmdzWzFdLCBhcmdzW2ldKTsKICAg
ICAgICBTeXN0ZW0uZXhpdCgwKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgU3lzdGVt
LmVyci5wcmludGxuKCJVc2FnZTogSmFwaXplIFstYyBjbGFzc25hbWUgLi4uIHwgLWYgemlw
ZmlsZSBwYWNrYWdlIC4uLl0iKTsKICAgIH0KICB9CgogIHB1YmxpYyBzdGF0aWMgYm9vbGVh
biBqYXBpemVDbGFzcyhTdHJpbmcgY25hbWUpIHRocm93cyBOb1N1Y2hNZXRob2RFeGNlcHRp
b24sIElsbGVnYWxBY2Nlc3NFeGNlcHRpb24sIENsYXNzTm90Rm91bmRFeGNlcHRpb24gewog
ICAgQ2xhc3MgYyA9IENsYXNzLmZvck5hbWUoY25hbWUpOwogICAgaW50IG1vZHMgPSBjLmdl
dE1vZGlmaWVycygpOwogICAgaWYgKCFNb2RpZmllci5pc1B1YmxpYyhtb2RzKSAmJiAhTW9k
aWZpZXIuaXNQcm90ZWN0ZWQobW9kcykpIHJldHVybiBmYWxzZTsKICAgIFN0cmluZyBlbnRy
eSA9IGMuZ2V0TmFtZSgpICsgIiMiOwogICAgU3RyaW5nIHR5cGUgPSBjLmlzSW50ZXJmYWNl
KCkgPyAiaW50ZXJmYWNlIiA6ICJjbGFzcyI7CiAgICBDbGFzcyBzdXAgPSBjOwogICAgaW50
IHNtb2RzID0gbW9kczsKICAgIHdoaWxlIChzdXAuZ2V0U3VwZXJjbGFzcygpICE9IG51bGwp
IHsKICAgICAgc3VwID0gc3VwLmdldFN1cGVyY2xhc3MoKTsKICAgICAgc21vZHMgPSBzdXAu
Z2V0TW9kaWZpZXJzKCk7CiAgICAgIGlmICghTW9kaWZpZXIuaXNQdWJsaWMoc21vZHMpICYm
ICFNb2RpZmllci5pc1Byb3RlY3RlZChzbW9kcykpIHsKICAgICAgICBTeXN0ZW0uZXJyLnBy
aW50KCJeIik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdHlwZSArPSAiOiIgKyBzdXAuZ2V0
TmFtZSgpOwogICAgICB9CiAgICB9CiAgICBDbGFzc1tdIGlmYWNlcyA9IGMuZ2V0SW50ZXJm
YWNlcygpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpZmFjZXMubGVuZ3RoOyBpKyspIHsK
ICAgICAgaW50IG1kcyA9IGlmYWNlc1tpXS5nZXRNb2RpZmllcnMoKTsKICAgICAgaWYgKE1v
ZGlmaWVyLmlzUHVibGljKG1kcykgfHwgTW9kaWZpZXIuaXNQcm90ZWN0ZWQobWRzKSkgewog
ICAgICAgIHR5cGUgKz0gIioiICsgaWZhY2VzW2ldLmdldE5hbWUoKTsKICAgICAgfQogICAg
fQogICAgcHJpbnRFbnRyeShlbnRyeSwgdHlwZSwgYy5nZXRNb2RpZmllcnMoKSk7CiAgICBG
aWVsZFtdIGZpZWxkcyA9IGMuZ2V0RmllbGRzKCk7CiAgICBNZXRob2RbXSBtZXRob2RzID0g
Yy5nZXRNZXRob2RzKCk7CiAgICBDb25zdHJ1Y3RvcltdIGNvbnN0cnMgPSBjLmdldENvbnN0
cnVjdG9ycygpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKysp
IHsKICAgICAgaW50IGRtb2RzID0gZmllbGRzW2ldLmdldERlY2xhcmluZ0NsYXNzKCkuZ2V0
TW9kaWZpZXJzKCk7CiAgICAgIGlmICghTW9kaWZpZXIuaXNQdWJsaWMoZG1vZHMpICYmICFN
b2RpZmllci5pc1Byb3RlY3RlZChkbW9kcykpIHsKICAgICAgICBTeXN0ZW0uZXJyLnByaW50
KCI+Iik7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgbW9kcyA9IGZpZWxkc1tp
XS5nZXRNb2RpZmllcnMoKTsKICAgICAgdHlwZSA9IGZpZWxkc1tpXS5nZXRUeXBlKCkuZ2V0
TmFtZSgpOwogICAgICBpZiAoTW9kaWZpZXIuaXNGaW5hbChtb2RzKSAmJiBNb2RpZmllci5p
c1N0YXRpYyhtb2RzKSAmJgogICAgICAgICAgTW9kaWZpZXIuaXNQdWJsaWMobW9kcykgJiYK
ICAgICAgICAgIChmaWVsZHNbaV0uZ2V0VHlwZSgpLmlzUHJpbWl0aXZlKCkgfHwKICAgICAg
ICAgICB0eXBlLmVxdWFscygiamF2YS5sYW5nLlN0cmluZyIpKSkgewogICAgICAgIHR5cGUg
Kz0gIjoiICsgZmllbGRzW2ldLmdldChudWxsKTsKICAgICAgfQogICAgICBwcmludEVudHJ5
KGMuZ2V0TmFtZSgpICsgIiMiICsgZmllbGRzW2ldLmdldE5hbWUoKSwgdHlwZSwgbW9kcyk7
CiAgICB9CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbnN0cnMubGVuZ3RoOyBpKyspIHsK
ICAgICAgZW50cnkgPSBjLmdldE5hbWUoKSArICIjKCI7CiAgICAgIENsYXNzW10gcGFyYW1z
ID0gY29uc3Ryc1tpXS5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICBTdHJpbmcgY29tbWEg
PSAiIjsKICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBwYXJhbXMubGVuZ3RoOyBqKyspIHsK
ICAgICAgICBlbnRyeSArPSBjb21tYSArIHBhcmFtc1tqXS5nZXROYW1lKCk7CiAgICAgICAg
Y29tbWEgPSAiLCI7CiAgICAgIH0KICAgICAgZW50cnkgKz0gIikiOwogICAgICB0eXBlID0g
ImNvbnN0cnVjdG9yIjsKICAgICAgQ2xhc3NbXSBleGNwcyA9IGNvbnN0cnNbaV0uZ2V0RXhj
ZXB0aW9uVHlwZXMoKTsKICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBleGNwcy5sZW5ndGg7
IGorKykgewogICAgICAgIHR5cGUgKz0gIioiICsgZXhjcHNbal0uZ2V0TmFtZSgpOwogICAg
ICB9CiAgICAgIHByaW50RW50cnkoZW50cnksIHR5cGUsIGNvbnN0cnNbaV0uZ2V0TW9kaWZp
ZXJzKCkpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRob2RzLmxlbmd0aDsg
aSsrKSB7CiAgICAgIGludCBkbW9kcyA9IG1ldGhvZHNbaV0uZ2V0RGVjbGFyaW5nQ2xhc3Mo
KS5nZXRNb2RpZmllcnMoKTsKICAgICAgaWYgKCFNb2RpZmllci5pc1B1YmxpYyhkbW9kcykg
JiYgIU1vZGlmaWVyLmlzUHJvdGVjdGVkKGRtb2RzKSkgewogICAgICAgIFN5c3RlbS5lcnIu
cHJpbnQoIn0iKTsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICB0cnkgewogICAg
ICAgIGlmICghbWV0aG9kc1tpXS5lcXVhbHMoYy5nZXRNZXRob2QobWV0aG9kc1tpXS5nZXRO
YW1lKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRo
b2RzW2ldLmdldFBhcmFtZXRlclR5cGVzKCkpKSkgewogICAgICAgICAgU3lzdGVtLmVyci5w
cmludCgiISIpOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICB9IGNhdGNo
IChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgewogICAgICAgIFN5c3RlbS5lcnIucHJpbnQo
Ik0iKTsKICAgICAgfQogICAgICBlbnRyeSA9IGMuZ2V0TmFtZSgpICsgIiMiICsgbWV0aG9k
c1tpXS5nZXROYW1lKCkgKyAiKCI7CiAgICAgIENsYXNzW10gcGFyYW1zID0gbWV0aG9kc1tp
XS5nZXRQYXJhbWV0ZXJUeXBlcygpOwogICAgICBTdHJpbmcgY29tbWEgPSAiIjsKICAgICAg
Zm9yIChpbnQgaiA9IDA7IGogPCBwYXJhbXMubGVuZ3RoOyBqKyspIHsKICAgICAgICBlbnRy
eSArPSBjb21tYSArIHBhcmFtc1tqXS5nZXROYW1lKCk7CiAgICAgICAgY29tbWEgPSAiLCI7
CiAgICAgIH0KICAgICAgZW50cnkgKz0gIikiOwogICAgICB0eXBlID0gbWV0aG9kc1tpXS5n
ZXRSZXR1cm5UeXBlKCkuZ2V0TmFtZSgpOwogICAgICBDbGFzc1tdIGV4Y3BzID0gbWV0aG9k
c1tpXS5nZXRFeGNlcHRpb25UeXBlcygpOwogICAgICBmb3IgKGludCBqID0gMDsgaiA8IGV4
Y3BzLmxlbmd0aDsgaisrKSB7CiAgICAgICAgdHlwZSArPSAiKiIgKyBleGNwc1tqXS5nZXRO
YW1lKCk7CiAgICAgIH0KICAgICAgcHJpbnRFbnRyeShlbnRyeSwgdHlwZSwgbWV0aG9kc1tp
XS5nZXRNb2RpZmllcnMoKSk7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIHB1Ymxp
YyBzdGF0aWMgdm9pZCBwcmludEVudHJ5KFN0cmluZyB0aGluZywgU3RyaW5nIHR5cGUsIGlu
dCBtb2RzKSB7CiAgICBpZiAoIU1vZGlmaWVyLmlzUHVibGljKG1vZHMpICYmICFNb2RpZmll
ci5pc1Byb3RlY3RlZChtb2RzKSkgcmV0dXJuOwogICAgU3lzdGVtLm91dC5wcmludCh0aGlu
ZyArICIgIik7CiAgICBTeXN0ZW0ub3V0LnByaW50KE1vZGlmaWVyLmlzUHVibGljKG1vZHMp
ID8gInB1YmxpYyAiIDogInByb3RlY3RlZCAiKTsKICAgIFN5c3RlbS5vdXQucHJpbnQoTW9k
aWZpZXIuaXNBYnN0cmFjdChtb2RzKSA/ICJhYnN0cmFjdCAiIDogImNvbmNyZXRlICIpOwog
ICAgU3lzdGVtLm91dC5wcmludChNb2RpZmllci5pc1N0YXRpYyhtb2RzKSA/ICJzdGF0aWMg
IiA6ICJpbnN0YW5jZSAiKTsKICAgIFN5c3RlbS5vdXQucHJpbnQoTW9kaWZpZXIuaXNGaW5h
bChtb2RzKSA/ICJmaW5hbCAiIDogIm5vbmZpbmFsICIpOwogICAgU3lzdGVtLm91dC5wcmlu
dGxuKHR5cGUpOwogIH0KCiAgcHVibGljIHN0YXRpYyB2b2lkIHByb2Nlc3NaaXAoU3RyaW5n
IGZuYW1lLCBTdHJpbmcgcGtnKSB0aHJvd3MgTm9TdWNoTWV0aG9kRXhjZXB0aW9uLCBJbGxl
Z2FsQWNjZXNzRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlv
biB7CiAgICBaaXBGaWxlIHogPSBuZXcgWmlwRmlsZShmbmFtZSk7CiAgICBFbnVtZXJhdGlv
biBlbnRzID0gei5lbnRyaWVzKCk7CiAgICBTdHJpbmcgcGtnRGlyID0gcGtnLnJlcGxhY2Uo
Jy4nLCAnLycpICsgIi8iOwogICAgd2hpbGUgKGVudHMuaGFzTW9yZUVsZW1lbnRzKCkpIHsK
ICAgICAgU3RyaW5nIHplID0gKChaaXBFbnRyeSllbnRzLm5leHRFbGVtZW50KCkpLmdldE5h
bWUoKTsKICAgICAgaWYgKHplLnN0YXJ0c1dpdGgocGtnRGlyKSAmJiB6ZS5lbmRzV2l0aCgi
LmNsYXNzIikpIHsKICAgICAgICBpZiAoamFwaXplQ2xhc3MoemUuc3Vic3RyaW5nKDAsIHpl
Lmxlbmd0aCgpIC0gNikucmVwbGFjZSgnLycsICcuJykpKSB7CiAgICAgICAgICBTeXN0ZW0u
ZXJyLnByaW50KCIqIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIFN5c3RlbS5lcnIu
cHJpbnQoIi0iKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgU3lzdGVtLmVy
ci5wcmludCgiXyIpOwogICAgICB9CiAgICAgIFN5c3RlbS5lcnIuZmx1c2goKTsKICAgIH0K
ICAgIFN5c3RlbS5lcnIucHJpbnRsbigiXG5Eb25lIHNjYW5uaW5nIGZvciAiICsgcGtnKTsK
ICB9Cn0K
--------------8A84F3000079C87690518845--