Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Verifying Dependencies in Eclipse

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →

Verifying Dependencies in Eclipse

Eclipse is a system of plugins, where multiple plugins come together to form any typical instance of the application. The core eclipse infrastructure is in itself a combination of plugins. With a large number of options available from a marketplace of plugins, where an end usr may choose to install just about any arbitrary mix of them on eclipse, ensuring compatibility between plugins in a chosen combination is important especially when considering that eclipse is now being used in all sorts of (sensitive and non-sensitive) contexts. In this talk I presented my ongoing work and experiences so far in checking if given a combination of plugins, all the stated dependencies of all the plugins are satisfied, and to see if any plugins have unnecessary, unstated or unsatisfied dependencies.

Avatar for Shivanshu Singh

Shivanshu Singh

April 29, 2013

Other Decks in Technology

Transcript

  1. Plugin based systems are pretty mainstream Deployed for serious commercial

    and noncommercial use Closed World Open World Marketplace of plugins 2
  2. 3

  3. “ How do I debug the Eclipse Plugin error ‘Plugin

    was unable to load class’ ? ” Missing dependencies not realized until its too late http://stackover"ow.com/questions/648024/how-do-i-debug-the-eclipse-plugin-error-plugin-was-unable-to-load-class http://stackover"ow.com/questions/9128132/eclipse-plugin-install-error http://androidforums.com/developer-101/543787-error-installing-adt-plugin-in-eclipse.html#post4343892 http://www.eclipsezone.com/eclipse/forums/t93278.rhtml http://stackover"ow.com/questions/1509511/eclipse-plugin-noclassde#ounderror-on-org-eclipse-jdt-ui-javaui http://stackover"ow.com/questions/11514883/con"icting-dependencies-while-installing-adt-plugin-for-eclipse-helios 4
  4. 5

  5. “ We try to encapsulate the logic as much as

    possible to be able to test with unit tests. What cannot be encapsulated is not tested. ” 7
  6. 8 Plugin testing beyond unit testing is: annoying distracting painful

    Lack of time, resources, infrastructure, combinatorial complexity Arbitrary dependency speci$cations Too many plugins, too many versions
  7. 9 Understanding user-speci$ed dependency speci$cations and how they map to

    the actual implementation Analysing artifacts for checking arbitrary dependency speci$cations Compatibility across version ranges
  8. Extract dependencies from the speci$cation and the implementation Analyse them

    for satisfaction in the Implementation Understand implied and/or unstated dependencies Compatibility across various versions 11 Solution Space Problem Space
  9. 12 package org.some; public class A { public void fn()

    {....} public String foo(int a) {....} private int process() { B b = new B(); boolean flag = B.go(); C c=new C(); c.callfn(“hello”); } } ------------------------------------------ package org.someother; public class C { void callfn(String x) {....} } package com.eother.some; public class B extends G { public boolean go() { return true; } } ------------------------------------------ package com.eother; public class G { .... } Problem Space Solution Scape
  10. 14 lib/jar! lib/jar! lib/jar! MANIFEST.MF! PLUGIN OSGi Plugin Manifest: UniqueName,

    Version Exports: packages Imports: libraries Exported Package
  11. 15 lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN lib/jar! lib/jar! lib/jar!

    MANIFEST.MF! PLUGIN OSGi Plugin Manifest: UniqueName, Version Exports: packages Imports: libraries other plugins
  12. 16 lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN lib/jar! lib/jar! lib/jar!

    MANIFEST.MF! PLUGIN lib/jar! lib/jar! MANIFEST.MF! PLUGIN OSGi Plugin Manifest: UniqueName, Version Exports: packages Imports: libraries other plugins external packages Exported Package
  13. 17 lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN lib/jar! lib/jar! lib/jar!

    MANIFEST.MF! PLUGIN lib/jar! lib/jar! MANIFEST.MF! PLUGIN OSGi Plugin Manifest: UniqueName, Version Exports: packages Imports: libraries other plugins external packages Host: (opt. for fragments)
  14. 18 lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN lib/jar! lib/jar! lib/jar!

    MANIFEST.MF! PLUGIN lib/jar! lib/jar! MANIFEST.MF! PLUGIN OSGi Plugin Manifest: UniqueName, Version Exports: packages Imports: libraries other plugins external packages Host: (opt. for fragments)
  15. 19 lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN FEATURE feature.xml! lib/jar!

    lib/jar! lib/jar! MANIFEST.MF! PLUGIN MANIFEST.MF! PL U GI N MANIFEST.MF! PL U GI N PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN MANIFEST.MF! PL U GI N MANIFEST.MF! PL U GI N lib/jar! lib/jar! MANIFEST.MF! PLUGIN OSGi Plugin Manifest: UniqueName, Version Exports: packages Imports: libraries other plugins external packages Host: (opt. for fragments) Eclipse Feature.xml: UniqueName, Version Includes: plugin a, plugin b, (if  q  then  plugin c) ….
  16. 20 lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN FEATURE feature.xml! lib/jar!

    lib/jar! lib/jar! MANIFEST.MF! PLUGIN MANIFEST.MF! PL U GI N MANIFEST.MF! PL U GI N PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN MANIFEST.MF! PL U GI N MANIFEST.MF! PL U GI N FEATURE feature.xml! lib/jar! lib/jar! MANIFEST.MF! PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN lib/jar! lib/jar! MANIFEST.MF! PLUGIN Eclipse Feature.xml: UniqueName, Version Includes: plugin a, plugin b, (if q then plugin c) …. Imports: plugin p version 2.1.2 feature x …. OSGi Plugin Manifest: UniqueName, Version Exports: packages Imports: libraries other plugins external packages Host: (opt. for fragments)
  17. OSGi Plugin Manifest: UniqueName, Version Exports: packages Imports: libraries other

    plugins external packages Host: (opt. for fragments) 21 lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN FEATURE feature.xml! lib/jar! lib/jar! lib/jar! MANIFEST.MF! PLUGIN MANIFEST.MF! PL U GI N MANIFEST.MF! PL U GI N PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN MANIFEST.MF! PL U GI N MANIFEST.MF! PL U GI N FEATURE feature.xml! lib/jar! lib/jar! MANIFEST.MF! PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN PLUGIN lib/ jar! lib/ jar! MANIFEST.MF! PLUGIN lib/jar! lib/jar! MANIFEST.MF! PLUGIN Eclipse Feature.xml: UniqueName, Version Includes: plugin a, plugin b, (if q then plugin c) …. Imports: plugin p version 2.1.2 feature x …. May include platform (OS, ARCH, WS, NL) conditions also
  18. 27 pluginA version= 2.4.0.201305 Import-Bundle= pluginB[1.1.0,2.0.2] Import-Package= package.some 1.4.2.1234 pluginX

    version= 5.1.2 exports= package.some 1.4.2 pluginB version= 1.2.4.qual pluginB version= 1.6.0 pluginB version= 1.0.0 pluginY version= 2.3.4.some exports= package.some 1.4.2.1234 pluginZ version= 2.0.0 HostBundle= pluginA 2.4.0.201305
  19. 28 pluginA version= 2.4.0.201305 Import-Bundle= pluginB[1.1.0,2.0.2] Import-Package= package.some 1.4.2.1234 pluginX

    version= 5.1.2 exports= package.some 1.4.2 pluginB version= 1.2.4.qual pluginB version= 1.6.0 pluginB version= 1.0.0 pluginY version= 2.3.4.some exports= package.some 1.4.2.1234 pluginZ version= 2.0.0 HostBundle= pluginA 2.4.0.201305 pluginA_2.4.0.201305 => (pluginB_1.2.4.qual || pluginB_1.6.0)
  20. 29 pluginA version= 2.4.0.201305 Import-Bundle= pluginB[1.1.0,2.0.2] Import-Package= package.some 1.4.2.1234 pluginX

    version= 5.1.2 exports= package.some 1.4.2 pluginB version= 1.2.4.qual pluginB version= 1.6.0 pluginB version= 1.0.0 pluginY version= 2.3.4.some exports= package.some 1.4.2.1234 pluginZ version= 2.0.0 HostBundle= pluginA 2.4.0.201305 pluginA_2.4.0.201305 => (pluginB_1.2.4.qual || pluginB_1.6.0) && pluginY_2.3.4.some
  21. 30 pluginA version= 2.4.0.201305 Import-Bundle= pluginB[1.1.0,2.0.2] Import-Package= package.some 1.4.2.1234 pluginX

    version= 5.1.2 exports= package.some 1.4.2 pluginB version= 1.2.4.qual pluginB version= 1.6.0 pluginB version= 1.0.0 pluginY version= 2.3.4.some exports= package.some 1.4.2.1234 pluginZ version= 2.0.0 HostBundle= pluginA 2.4.0.201305 pluginA_2.4.0.201305 => (pluginB_1.2.4.qual || pluginB_1.6.0) && pluginY_2.3.4.some pluginZ_2.0.0 => pluginA_2.4.0.201305
  22. 31 feature.xml manifest.mf Speci$cation Dependency Extraction 1 Spec:  imp,exp  

    Feature Model: plugin_b_1.1.1.201 => plugin_a_2.4.6_qual plugin_c_4.0.3) => ( plugin_w_0.0.0 && org_eclipse_core_3.4.1 ) feature_a_1.1.1.I2011 => ( plugin_b_1.1.1.201 && plugin_c_4.0.3 && (_OS_linux => plugin_g) && feature_b_0.0.0 ) one of (_OS_linux _OS_macosx, _OS_solaris, _OS_win32 .... ) ….
  23. Impl:  imp,  exp  (funcSig)     &  interfaces  +  inheritances

      Interface Extraction from Plugins 2 32 Spec:  imp,exp   feature.xml manifest.mf Feature Model: plugin_b_1.1.1.201 => plugin_a_2.4.6_qual plugin_c_4.0.3) => ( plugin_w_0.0.0 && org_eclipse_core_3.4.1 ) feature_a_1.1.1.I2011 => ( plugin_b_1.1.1.201 && plugin_c_4.0.3 && (_OS_linux => plugin_g) && feature_b_0.0.0 ) one of (_OS_linux _OS_macosx, _OS_solaris, _OS_win32 .... ) …. Speci$cation Dependency Extraction 1
  24. 34 package org.some;! public class A {! public void fn()

    {....}! public String foo(int a) {....}! private int process() {! B b = new B(); boolean flag = B.go();! C c=new C(); c.callfn(“hello”);! }! }! -------------------------------------------! package org.someother;! public class C {! void callfn(String x) {....}! }! package com.eother.some;! public class B extends G {! public boolean go() {! return true;! }! }! ----------------------------------! package com.eother;! public class G {! ....! }! ! ! ! pluginX pluginY
  25. 35 package org.some;! public class A {! public void fn()

    {....}! public String foo(int a) {....}! private int process() {! B b = new B(); boolean flag = B.go();! C c=new C(); c.callfn(“hello”);! }! }! -------------------------------------------! package org.someother;! public Class C {! void callfn(String x) {....}! }! package com.eother.some;! public class B extends G {! public boolean go() {! return true;! }! }! ----------------------------------! package com.eother;! public class G {! ....! }! ! ! ! pluginX pluginY Imports: boolean com.eother.some.B.go () void org.someother.C.callfn (java.lang.String) Exports: void org.some.A.fn () java.lang.String org.some.A.foo (int)
  26. 36 package org.some;! public class A {! public void fn()

    {....}! public String foo(int a) {....}! private int process() {! B b = new B(); boolean flag = B.go();! C c=new C(); c.callfn(“hello”);! }! }! -------------------------------------------! package org.someother;! public Class C {! void callfn(String x) {....}! }! package com.eother.some;! public class B extends G {! public boolean go() {! return true;! }! }! ----------------------------------! package com.eother;! public class G {! ....! }! ! ! ! pluginX pluginY Imports: boolean com.eother.some.B.go () void org.someother.C.callfn (java.lang.String) Exports: void org.some.A.fn () java.lang.String org.some.A.foo (int) void org.someother.C.callfn (java.lang.String)
  27. 37 package org.some;! public class A {! public void fn()

    {....}! public String foo(int a) {....}! private int process() {! B b = new B(); boolean flag = B.go();! C c=new C(); c.callfn(“hello”);! }! }! -------------------------------------------! package org.someother;! public Class C {! void callfn(String x) {....}! }! package com.eother.some;! public class B extends G {! public boolean go() {! return true;! }! }! ----------------------------------! package com.eother;! public class G {! ....! }! ! ! ! pluginX pluginY Imports: boolean com.eother.some.B.go () void org.someother.C.callfn (java.lang.String) Exports: void org.some.A.fn () java.lang.String org.some.A.foo (int) void org.someother.C.callfn (java.lang.String)
  28. 38 package org.some;! public class A {! public void fn()

    {....}! public String foo(int a) {....}! private int process() {! B b = new B(); boolean flag = B.go();! C c=new C(); c.callfn(“hello”);! }! }! -------------------------------------------! package org.someother;! public Class C {! void callfn(String x) {....}! }! package com.eother.some;! public class B extends G {! public boolean go() {! return true;! }! }! ----------------------------------! package com.eother;! public class G {! ....! }! ! ! ! pluginX pluginY Imports: boolean com.eother.some.B.go () void org.someother.C.callfn (java.lang.String) Exports: void org.some.A.fn () java.lang.String org.some.A.foo (int) void org.someother.C.callfn (java.lang.String) Imports: Exports: boolean com.eother.some.B.go()
  29. 39 package org.some;! public class A {! public void fn()

    {....}! public String foo(int a) {....}! private int process() {! B b = new B(); boolean flag = B.go();! C c=new C(); c.callfn(“hello”);! }! }! -------------------------------------------! package org.someother;! public Class C {! void callfn(String x) {....}! }! package com.eother.some;! public class B extends G {! public boolean go() {! return true;! }! }! ----------------------------------! package com.eother;! public class G {! ....! }! ! ! ! pluginX pluginY Imports: boolean com.eother.some.B.go () void org.someother.C.callfn (java.lang.String) Exports: void org.some.A.fn () java.lang.String org.some.A.foo (int) void org.someother.C.callfn (java.lang.String) Imports: Exports: boolean com.eother.some.B.go() Inheritance: com.eother.some.B com.eother.G
  30. Why bytecode? •  fully quali$ed names, signatures and access opcodes

    •  no need to to do all sorts of resolution –  (parsing and extraction is simpler) •  that is what we have available from plugin dist anyway ASM all purpose Java bytecode manipulation and analysis framework several interfaces provided: ClassVisitor, MethodVisitor http://asm.ow2.org/ 40 Parsing Bytecode
  31. Linking & Inter-Plugin Dependency Analysis 3 41 Interface Extraction from

    Plugins 2 Impl:  imp,  exp  (funcSig)     &  interfaces  +  inheritances   Spec:  imp,exp   feature.xml manifest.mf Feature Model: plugin_b_1.1.1.201 => plugin_a_2.4.6_qual plugin_c_4.0.3) => ( plugin_w_0.0.0 && org_eclipse_core_3.4.1 ) feature_a_1.1.1.I2011 => ( plugin_b_1.1.1.201 && plugin_c_4.0.3 && (_OS_linux => plugin_g) && feature_b_0.0.0 ) one of (_OS_linux _OS_macosx, _OS_solaris, _OS_win32 .... ) …. Speci$cation Dependency Extraction 1
  32. 42 class/interface   import A .... void ba { A.go

    (); } .... pluginW package org.some;! public class A {! public void fn() {....}! public String foo(int a) {....}! private int process() {! B b = new B(); ! boolean flag = B.go();! C c=new C(); c.callfn(“hello”);! }}! package org.someother;! public Class C {! void callfn(String x) {....}! }! package com.eother.some;! public class B extends G {! public boolean go() {! return true;! }! }! ! package com.eother;! public class G {! ....! }! ! ! pluginX pluginY Imports: boolean com.eother.some.B.go () void org.someother.C.callfn (java.lang.String) Exports: void org.some.A.fn () java.lang.String org.some.A.foo (int) void org.someother.C.callfn (java.lang.String) Imports: Exports: boolean com.eother.some.B.go() Inheritance: com.eother.some.B com.eother.G A B void A.go () Linking & Inter-Plugin Dependency Analysis 3
  33. B T pluginY 43 class/interface   import A .... void

    ba { A.go (); } .... pluginW A B void A.go () Linking & Inter-Plugin Dependency Analysis 3
  34. B T pluginY 44 class/interface   K { void go()

    {} } pluginZ C pluginP G S import A .... void ba { A.go (); } .... pluginW void K.go() [pluginY, pluginP, pluginZ] A B void A.go () Linking & Inter-Plugin Dependency Analysis 3
  35. B T pluginY 45 class/interface   K { void go()

    {} } pluginZ C pluginP G S import A .... void ba { A.go (); } .... pluginW Constraint: pluginW => ( pluginY && pluginP && pluginZ ) void K.go() [pluginY, pluginP, pluginZ] A B void A.go () Linking & Inter-Plugin Dependency Analysis 3
  36. 46 com.zink.fly.buzz_1.2.1.201104282140 => (org.eclipse.jface_3.8.102.v20130123.162658 && org.eclipse.ui.workbench_3.104.0.v20130204.164612 && com.zink.fly.buzz_1.2.1.201104282140) || (org.eclipse.jface_3.8.102.v20130123.162658

    && com.zink.fly.buzz_1.2.1.201104282140) com.zink.fly.buzz_1.2.1.201104282140 => org.eclipse.jface_3.8.102.v20130123.162658 com.zink.fly.buzz_1.2.1.201104282140 => org.eclipse.swt.cocoa.macosx.x86.64_3.100.1.v4236b com.zink.fly.buzz_1.2.1.201104282140 => (org.eclipse.ui.workbench_3.104.0.v20130204.164612 && com.zink.fly.buzz_1.2.1.201104282140) com.zink.fly.buzz_1.2.1.201104282140 => org.eclipse.ui.workbench_3.104.0.v20130204.164612 javax.wsdl_1.6.2.v201012040545 => JAVA.CLASSES.SDK || javax.xml_1.3.4.v201005080400 javax.wsdl_1.6.2.v201012040545 => JAVA.CLASSES.SDK || javax.xml_1.3.4.v201005080400 || (javax.xml_1.3.4.v201005080400 && JAVA.CLASSES.SDK) javax.xml.bind_2.1.9.v201005080401 => JAVA.CLASSES.SDK || javax.xml_1.3.4.v201005080400 org.apache.ant_1.8.3.v201301120609 => (JAVA.CLASSES.SDK && com.jcraft.jsch_0.1.46.v201205102330) org.apache.ant_1.8.3.v201301120609 => (JAVA.CLASSES.SDK && org.apache.ant_1.8.3.v201301120609) org.apache.ant_1.8.3.v201301120609 => (JAVA.CLASSES.SDK && org.junit_3.8.2.v3.8.2.v20100427.1100) || (JAVA.CLASSES.SDK && org.junit_4.10.0.v4.10.0.v20120426.0900) org.apache.ant_1.8.3.v201301120609 => (JAVA.CLASSES.SDK && org.python.pydev.shared.interactive.console_2.7.3.2013031601) || (JAVA.CLASSES.SDK && org.apache.commons.logging_1.0.4.v201101211617) org.apache.ant_1.8.3.v201301120609 => JAVA.CLASSES.SDK || javax.xml_1.3.4.v201005080400 org.apache.ant_1.8.3.v201301120609 => JAVA.CLASSES.SDK || javax.xml_1.3.4.v201005080400 || (javax.xml_1.3.4.v201005080400 && JAVA.CLASSES.SDK) org.apache.ant_1.8.3.v201301120609 => com.jcraft.jsch_0.1.46.v201205102330 org.apache.ant_1.8.3.v201301120609 => org.apache.log4j_1.2.15.v201012070815 Linking & Inter-Plugin Dependency Analysis 3 Constraints Set
  37. 47 Constraints: (plugin_b_1.1.1.201 || plugin_c_4.0.3) => ( plugin_a_1.2.4 && plugin_w_1.1.5.u7256

    ) …. Import (invokation) Satisfaction Report Linking & Inter-Plugin Dependency Analysis 3 Interface Extraction from Plugins 2 Impl:  imp,  exp  (funcSig)     &  interfaces  +  inheritances   Spec:  imp,exp   feature.xml manifest.mf Feature Model: plugin_b_1.1.1.201 => plugin_a_2.4.6_qual plugin_c_4.0.3) => ( plugin_w_0.0.0 && org_eclipse_core_3.4.1 ) feature_a_1.1.1.I2011 => ( plugin_b_1.1.1.201 && plugin_c_4.0.3 && (_OS_linux => plugin_g) && feature_b_0.0.0 ) one of (_OS_linux _OS_macosx, _OS_solaris, _OS_win32 .... ) …. Speci$cation Dependency Extraction 1
  38. 48 Constraints: (plugin_b_1.1.1.201 || plugin_c_4.0.3) => ( plugin_a_1.2.4 && plugin_w_1.1.5.u7256

    ) …. Import (invokation) Satisfaction Report Linking & Inter-Plugin Dependency Analysis 3 Interface Extraction from Plugins 2 Impl:  imp,  exp  (funcSig)     &  interfaces  +  inheritances   Spec:  imp,exp   feature.xml manifest.mf Feature Model: plugin_b_1.1.1.201 => plugin_a_2.4.6_qual plugin_c_4.0.3) => ( plugin_w_0.0.0 && org_eclipse_core_3.4.1 ) feature_a_1.1.1.I2011 => ( plugin_b_1.1.1.201 && plugin_c_4.0.3 && (_OS_linux => plugin_g) && feature_b_0.0.0 ) one of (_OS_linux _OS_macosx, _OS_solaris, _OS_win32 .... ) …. Speci$cation Dependency Extraction 1 Consistency Report Consistency Check 4
  39. 49

  40. 51   Plugins 766 Features 86 Imports 197188 (external &

    non-java & non-optional ) Feature Model entries 4237 Constraints entries 9756 Time ~ 3 min A typical eclipse installation
  41. 52   void org.apache.xmlbeans.XmlCursor.push () Importing Plugins org.mozilla.javascript 1.7.2.v201005080400 Exporting

    Plugins -- boolean org.apache.xmlbeans.XmlCursor$TokenType.isAnyAttr () boolean org.apache.xmlbeans.XmlCursor$TokenType.isAttr () boolean org.apache.xmlbeans.XmlCursor$TokenType.isComment () org.apache.xmlbeans.XmlObject org.apache.xmlbeans.XmlObject$Factory.newInstance () org.apache.xmlbeans.XmlObject org.apache.xmlbeans.XmlObject$Factory.parse (java.lang.String,) void org.apache.xmlbeans.XmlCursor.dispose () .... .... Plugin: org.mozilla.javascript version= 1.7.2.v201005080400 Spec. missing package import: org.apache.xmlbeans
  42. 53 void org.eclipse.jdt.internal.corext.dom. Modi$erRewrite.setVisibility (….) Importers com.stateo%ow.eclipse.tane 1.3.1.201104282140 Exporters --

    Plugin: com.stateo"ow.eclipse.tane version= 1.3.1.201104282140 Spec: import-package: org.eclipse.idt.internal.corext Still, the function: void org.eclipse.jdt.internal.corext.dom. Modi$erRewrite.setVisibility (….) does not exist! Exists: org.eclipse.jdt.internal.corext.$x.LinkedProposalPositionGroup$PositionInformation org.eclipse.jdt.internal.corext.dom.Modi$erRewrite.setVisibility (….) instead of: void org.eclipse.jdt.internal.corext.dom.Modi$erRewrite.setVisibility (….) A case of API evolution ?
  43. 62   Continue analysis of plugin compatibility across (user-speci$ed) version

    ranges Discussion on the design of a module system based on observations from eclipse Study API Usage evolution in Java and in an ecosystem like Eclipse (Based on historical data from plugins on deprecated api and evolution)
  44. 63   Solution Space Problem Space Constraints Feature Model Import

    (invokation) Satisfaction Report Consistency Report Analysis of user-speci$ed dependencies over version ranges Module system design based on observations from eclipse Deprecation, api and its usage evolution   Consistency Check K { void fn() {} } import A .... void ba {A.fn(); } .... org.mozilla.javascript Spec. missing package import The function: void ….Modi$erRewrite .setVisibility (….) does not exist! http://shivanshukumar.github.io/PluginAnalyser/ 4 3 2 1