Nødvendige ændringer, når du benytter 3.0-mekanismer og API'er

I dette afsnit beskrives de ændringer, der er nødvendige, hvis du forsøger at ændre din 2.1-plugin, så den kan benytte 3.0-mekanismer og -API'er.

Væk fra org.eclipse.core.runtime.compatibility

Eclipse 3.0-runtime er meget anderledes. Den underliggende implementering er baseret på specifikationen i OSGi-strukturen. Eclipse 3.0-runtime omfatter et kompatibilitetslag (i plugin'en org.eclipse.core.runtime.compatibility), som bibeholder 2.1-API'erne. Plugin-udviklere, som er interesseret i mere ydeevne og flere funktioner, skal overveje at benytte 3.0-API'er og fjerne deres afhængighed i kompatibilitetslaget. Kompatibilitetskoden viser sig tre forskellige steder:

Teksten nedenfor indeholder flere oplysninger om, hvilke klasser og metoder der er der af kompatibilitetsmæssige årsager, samt en vejledning i, hvordan du opdaterer plugin'en.

Plugins og bundter

Eclipse-runtime er refactoret til to dele: klasseindlæsning og den nødvendige styring samt styring af udvidelser/udvidelsespunkter. Denne opdeling gør det muligt at benytte OSGi-strukturspecifikationerne for klasseindlæsning og den nødvendige styring naturligt/uden besvær. Dette gør det igen muligt at benytte en bred vifte af muligheder i runtime, fra dynamisk installation/opdatering/fjernelse af installation af plugin til sikkerhed og øgede konfigurationsmuligheder.

Vi taler fortsat om plugins, men i den nye runtime er en plugin faktisk et bundt plus nogle udvidelser og udvidelsespunkter. Termen bundt er defineret af OSGi-strukturspecifikationen og henviser til en samling typer og ressourcer og tilknyttede, nødvendige oplysninger mellem bundter. Udvidelsesdatabasen er den nye form for plugin-registreringsdatabase og indeholder kun oplysninger om udvidelser og udvidelsespunkter. API'et til udvidelsesdatabasen er stort set den samme som API'et til den relevante plugin-registreringsdatabase. Der er flere oplysninger under Registreringsdatabaser.

I Eclipse 2.x-runtime har plugin-objekter flere roller og ansvarsområder:

I Eclipse 3.0-runtime-billedet factores disse roller og ansvarsområder til særskilte objekter.

Bundle
Bundter er OSGis modularitetsenhed. Der er én classloader pr. bundt, og der er mulighed for at konstruere Eclipse-lignende afhængighedsgrafer for klasseindlæsning mellem bundter. Bundter har livscyklusser for start og stop, og OSGi-strukturen videresender bundtrelaterede aktiviteter, f.eks. installér, fortolk, start, stop, fjern installation ...) til interesserede. Til forskel fra Eclipse-klassen Plugin, kan OSGi-klassen Bundle ikke udvides. Det vil sige, at udviklere ikke har mulighed for at definere deres egne bundtklasser.
BundleActivator
BundleActivator er en grænseflade defineret af OSGi-strukturen. Hvert bundt kan definere en bundtaktiveringsklasse, lidt på samme måde som en plugin kan definere en Plugin-klasse. Den angivne klasse er oprettet af strukturen og brugt til at implementere start()- og stop()-livscyklusbehandlingen. Der er dog en væsentlig forskel i karakteren af denne livscyklusbehandling. I Eclipse er det almindeligt, men ikke anbefalesværdigt, at Plugin-klasserne både står for initialisering og registrering. I OSGi skal aktiveringsfunktionerne kun foretage registrering. Hvis der skal foretages en stor mængde initialiseringer (eller andet arbejde) i BundleActivator.start(), kan det virke hæmmende på systemets reaktionstid.
BundleContext
BundleContexts er OSGis mekanisme til visning af generelle systemfunktioner for individuelle bundter. Hvert bundt har en entydig og privat forekomst af BundleContext, som de kan bruge til at få adgang til systemfunktioner, f.eks. getBundles(), hvis de vil finde alle bunder i systemet.
Plugin
Den nye Plugin minder meget om den oprindelige Eclipse-klasse Plugin med følgende undtagelser: Plugin-objekter kræves og styres ikke længere af runtime, og forskellige metoder er forældet. Det er hovedsageligt en mekanisme, som stiller en række nyttige funktioner og mekanismer til rådighed, men som ikke længere er absolut nødvendig. En hel del af de funktioner, der stilles til rådighed her, er også tilgængelige i Platform-klassen i runtime.

Plugin implementerer også BundleActivator. Dette skyldes, at det er nemmere at have ét centralt objekt, som repræsenterer en plugins livscyklus og semantik. Bemærk dog, at dette ikke berettiger til en ivrig initialisering af datastrukturer, som er almindelig i plugins i dag. Vi kan ikke understrege nok, at plugins kan aktiveres, fordi der blev henvist til en ret perifer klasse under validering af en klasse i en anden plugin. Det vil sige, at blot fordi din plugin er aktiveret, behøver det ikke betyde, at der er behov for den funktion, den udfører. Bemærk også, at du frit kan definere en anden BundleActivator-klasse eller vælge slet ikke at have en bundtaktiveringsfunktion.

De trin, der er nødvendige for at overføre en 2.x Plugin-klasse til Eclipse 3.0, afhænger af, hvad klassen gør. Som beskrevet ovenfor, falder størstedelen af startlivscyklusarbejdet i en af følgende kategorier:

Initialisering
Datastruktur- og modelinitialisering foretages ofte i Plugin.startup(). Den naturlige/mest oplagte tilknytning vha. mapping ville være at gøre dette arbejde i en BundleActivator.start(), det vil sige at lade funktionen være i Plugin. Dette frarådes på det kraftigste. Ligesom 2.x-plugins kan 3.0-plugins/bundter startes af mange forskellige årsager i mange forskellige situationer.
Et godt eksempel til beskrivelse af dette stammer fra Eclipse 2.0-tiden. Der var en plugin, som initialiserede en stor model, der krævede indlæsning af omkring 11 MB kode og mange megabyte data. Der var helt almindelige brugstilfælde, hvor denne plugin blev aktiveret for at finde ud af, om den projektikon, der blev vist i Navigator, skulle dekoreres med en bestemt markup. Testen krævede ikke noget af den initialisering, der blev foretaget i startup(), men alligevel skulle alle brugere i alle usecases betale for bruge af hukommelse og tid på grund af denne ivrige initialisering.
Alternativet er at foretage en sådan initialisering i den klassiske lazy-stil. I stedet for f.eks. at initialisere modeller, når plugin'en/bundtet aktiveres, aktiveres de, når der rent faktisk er brug for dem, dvs. via en centraliseret modeladgangsmetode. For mange usecases vil dette svare til næsten samme tidspunkt, men i andre tilfælde ville denne metode udskyde initialiseringen (måske uendeligt). Vi anbefaler, at du, når du overfører 2.1-plugins, bruger tid på at overveje den benyttede initialiseringsstrategi.
Registrering
Plugin-start er et godt tidspunkt at registrere f.eks. lytteprogrammer og serviceprogrammer på, og at starte programdele, der behandler i baggrunden (f.eks. lytter på en socket). Plugin.start() kan være et fornuftigt sted at foretage dette arbejde. Det kan også være fornuftigt at udskyde det, til det sættes i gang af noget andet, f.eks. hvis en bestemt funktion eller et bestemt dataelement bruges.
Globale plugin-data
Plugin-klassen kan fortsat spille denne rolle. Det væsentlige er, at du ikke længere kan få adgang til Plugin-objekter globalt via en systemstyret liste. I Eclipse 2.x kunne du finde ethvert plugins Plugin-objekt via plugin-registreringsdatabasen. Det er ikke længere muligt. I de fleste tilfælde kræves denne type adgang ikke. Typisk bruges de plugins, der er adgang til via registreringsdatabasen, snarere som generiske Plugins i stedet for som kald til domænespecifikke metoder. Du kan opnå tilsvarende muligheder ved at få adgang til og manipulere de tilsvarende Bundle-objekter.

Registreringsdatabaser og plugin-modellen

I den nye runtime er der en adskillelse mellem de oplysninger og strukturer, der er behov for at kunne udføre en plugin, og dem der vedrører en plugins udvidelser og udvidelsespunkter. De førstnævnte defineres og styres af OSGi-strukturspecifikationen. De sidstnævnte er Eclipse-specifikke koncepter og tilføjes af Eclipse-runtime-koden. Deraf følger, at den oprindelige plugin-registreringsdatabase og de relaterede objekter er blevet opdelt i OSGi-bundter og en Eclipse-udvidelsesregistreringsdatabase.

De dele af IPluginRegistry, der beskæftiger sig med udførelsesspecifikationer, f.eks. IPluginDescriptor, ILibrary, IPrequisite, er forældet og de tilbageværende dele, der vedrører udvidelser og udvidelsespunkter, er flyttet til IExtensionRegistry. De såkaldte modelobjekter, der vedrører plugin-registreringsdatabasen som sådan, er nu forældede. Disse typer blev præsenteret og oprettet af runtime primært for at understøtte værktøjer som f.eks. PDE. Desværre var det ofte sådan, at det informationsniveau, der var brug for, oversteg runtimes muligheder eller interesser, f.eks. at huske linjenumre for elementer i plugin.xml, og i sidste ende blev de mulige brugere af runtime-oplysningerne nødt til at vedligeholde deres egen struktur alligevel.

I den nye runtime har vi reevalueret de faciliteter, som runtime stillede til rådighed, og stiller nu kun de faciliteter til rådighed, som enten er afgørende for runtime-udførelsen, eller som det er utroligt besværligt for andre at udføre. Som nævnt ovenfor er modelobjekterne i plugin-registreringsdatabasen forældede, ligesom plugin-analyse-API'et. Den nye udvidelsesregistreringsdatabase vedligeholder de væsentligste udvidelsesrelaterede oplysninger. En ny state-struktur (se org.eclipse.osgi.service.resolver.State og venner) repræsenterer og tillader manupulering med de væsentligste udførelsesrelaterede oplysninger.

NL-fragmentstruktur

I Eclipse 3.0 er NL-fragmentstrukturen opdateret, så den er mere konsekvent. Tidligere blev det antaget, at oversættelser af filer som f.eks. plugin.properties var inde i JAR'er, som blev stillet til rådighed af fragmenter. Da de oprindelige filer er placeret i roden af den relevante værts-plugin, ville det være mere logisk at placere de oversatte filer i roden af NL-fragmenterne. Eksempel:

  org.eclipse.ui.workbench.nl/
     fragment.xml
     plugin_fr.properties
     plugin_pt_BR.properties
     ...
     nl1.jar

Bemærk, at filen nl1.jar tidligere ville have indeholdt oversættelsen af plugin.properties. Disse filer er nu placeret i roden af fragmentet, og JAR indeholder oversættelsen af ressourcer, der kan oversættes (dvs. filer, der er indlæst via klasseindlæserfunktionen) i værts-plugin'en.

Eclipse 2.1 NL-fragmentstrukturen understøttes selvfølgelig stadig for 2.1-værts-plugins, der udføres i Eclipse 3.0. Du kan dog ikke bruge et 2.1 NL-fragment i en 3.0-plugin. Fragmentet skal opdateres til den nye struktur.

Oversigt over API-ændringer

org.eclipse.core.boot (pakken org.eclipse.core.boot)

Hele pakken org.eclipse.core.boot er forældet. BootLoader er flettet sammen med org.eclipse.core.runtime.Platform, da det ikke længere gav mening at have en opdeling mellem start og runtime. Bemærk, at plugin'en org.eclipse.core.boot er brudt op, og al koden flyttet til enten den nye runtime eller til kompatibilitetslaget.

IPlatformConfiguration har altid været en type, der defineres af og til Eclipses installations/opdateringskomponent. Med omorganiseringen af runtime har vi kunnet placere denne type på den korrekte placering igen. Denne klasse forbliver stort set uændret og er pakket som org.eclipse.update.configurator.IPlatformConfiguration.

IPlatformRunnable er flyttet til org.eclipse.core.runtime.IPlatformRunnable.

IExtension og IExtensionPoint (pakken org.eclipse.core.runtime)

Metoden getDeclaringPlugin() (på begge klasser) giver et opadgående link til den plugin, der erklærer henholdsvis udvidelsen og udvidelsespunktet. Den nye registreringsdatabasemodel adskiller udførelsesaspekterne af plugins fra udvidelses/udvidelsespunktaspekterne og indeholder ikke længere IPluginDescriptors. Brugerne af denne API skal overveje at benytte den nye metode getParentIdentifier(), som findes i både IExtension og IExtensionPoint.

ILibrary, IPluginDescriptor, IPluginRegistry og IPrerequisite (pakken org.eclipse.core.runtime)

I den oprindelig runtime vedligeholdt plugin-registreringsdatabasen et fuldstændigt billede af runtime-konfigurationen. I Eclipse 3.0 er dette billede fordelt på OSGi-strukturen og udvidelsesregistreringsdatabasen. Disse klasser er som sådan forældet. Forældelsesmeddelelserne indeholder oplysninger om, hvordan du opdaterer din kode.

Platform og Plugin (pakken org.eclipse.core.runtime)

I den nye runtime er Plugin-objekterne ikke længere styret af runtime, og du kan derfor ikke få adgang til dem generisk via platformen. På samme måde findes plugin-registreringsdatabasen ikke længere, og den giver ikke længere adgang til plugin-deskriptorerne. Der findes dog relevante erstatningsmetoder. Du kan finde oplysninger om dem i det Javadoc, der hører til de forældede metoder i disse klasser.

org.eclipse.core.runtime.model (pakken org.eclipse.core.runtime.model)

Alle typer i denne pakke er nu forældet. Der er flere oplysninger i omtalen af registreringsdatabaser.

IWorkspaceRunnable og IWorkspace.run (pakken org.eclipse.core.resources)

Klienter til metoden IWorkspace.run(IWorkspaceRunnable,IProgressMonitor) skal genoverveje deres brug af denne metode og i stedet overveje at bruge den rigere metode IWorkspace.run(IWorkspaceRunnable,ISchedulingRule,int,IProgressMonitor). Den gamle IWorkspace.run-metode sætter en lås på hele arbejdsområdet, så lang tid det tager at udføre IWorkspaceRunnable. Det betyder, at en funktion, som udføres vha. denne metode, aldrig vil kunne udføres samtidig med andre funktioner, som ændrer arbejdsområdet. I Eclipse 3.0 er mange funktioner, som det tager lang tid at udføre, flyttet til baggrundsprogramdele (thread), så sandsynligheden for, at der forekommer konflikter mellem forskellige funktioner, er øget betragteligt. Hvis en modal forgrundsfunktion blokeres af en langvarig baggrundsfunktion, bliver brugergrænsefladen blokeret, indtil baggrundsfunktioner er afsluttet, eller indtil en af funktionerne annulleres.

Den foreslåede løsning består i at ændre alle referencer til gamle IWorkspace.run, så de nu benytter den nye metode med en planlægningsregelparameter. Planlægningsreglen skal være den mest finmaskede regel, som omfatter regler for alle ændringer, som funktionen foretager. Hvis funktionen forsøger at ændre ressourcer uden for omfanget af planlægningsreglen, opstår der en runtime-undtagelse. Den præcise planlægningsregel, som kræves af en given arbejdsområdefunktion, er ikke angivet og kan ændres, afhængig af udbyderen af et installeret opbevaringssted på et givent projekt. Factory-reglen IResourceRuleFactory skal bruges til at indhente planlægningsreglen for en funktion, der ændrer ressourcer. Hvis du ønsker det, kan du bruge en MultiRule til at angive flere ressourceregler, og MultiRule.combine-metoden kan bruges til at kombinere regler fra forskellige ressourceændrende funktioner.

Hvis der ikke kræves låsning, kan du bruge en null-planlægningsregel. Det vil gøre det muligt for den igangværende funktion at ændre alle ressourcer på arbejdsområdet, men det forhindrer ikke andre programdele i også at ændre arbejdsområdet samtidig. Hvis du skal foretage enkle ændringer af arbejdsområdet, er dette ofte den nemmeste og mest samtidighedsvenlige løsning.

IWorkbenchPage (pakken org.eclipse.ui)

IEditorDescriptor (pakken org.eclipse.ui)

ISharedImages (pakken org.eclipse.ui)

IWorkbenchActionConstants (pakken org.eclipse.ui)

IWorkbenchPreferenceConstants (pakken org.eclipse.ui)

IExportWizard (pakken org.eclipse.ui)

IImportWizard (pakken org.eclipse.ui)

INewWizard (pakken org.eclipse.ui)

WorkbenchHelp (pakken org.eclipse.ui.help)

IHelp (pakken org.eclipse.help)

ITextEditorActionConstants (pakken org.eclipse.ui.texteditor)

IAbstractTextEditorHelpContextIds (pakken org.eclipse.ui.texteditor)

BasicTextEditorActionContributor (pakken org.eclipse.ui.texteditor)

TextEditorActionContributor (pakken org.eclipse.ui.editors.text)

annotationTypes-udvidelsespunkt (plugin'en org.eclipse.ui.editors)

Der er nu kommet et eksplicit begreb, nemlig en annotationstype. Se Annotation.getType() og Annotation.setType(). En annotationstype kan ændre sig i løbet af sit liv. Der er tilføjet et nyt udvidelsespunkt til erklæring af annotationstyperne: "org.eclipse.ui.editors.annotationTypes". En annotationstype har et navn og kan erklæres som en undertype til en anden erklæret annotationstype. En erklæring af en annotationstype kan også bruge attributterne "markerType" og "markerSeverity" for at angive, at markeringerne for en bestemt type og et bestemt niveau skal repræsenteres i teksteditorer som annotationer af en bestemt annotationstype. Attributterne "markerType" og "markerSeverity" i "org.eclipse.ui.editors.markerAnnotationSpecification" bør ikke længere bruges. Markeringsannotationsspecifikationer bliver på den måde uafhængige af markeringer, og navnet bliver på den måde misvisende. Navnet bibeholdes dog for at sikre bagudgående kompatibilitet.

Forekomster af underklasser af AbstractMarkerAnnotationModel registrerer og angiver automatisk de korrekte annotationstyper for annotationer, de opretter på baggrund af markeringer. For rent programmæssigt at kunne genkalde annotationstypen for en bestemt markering eller for et par bestående af markerType og markerSeverity skal du bruge org.eclipse.ui.texteditor.AnnotationTypeLookup.

IAnnotationAccessExtension giver adgang til annotationstypehierarkiet. For en given annotationstype kan du få en kæde af supertyper og kontrollere, om en annotationstype er en undertype til en anden annotationstype. DefaultMarkerAnnotationAccess implementerer denne grænseflade.

markerAnnotationSpecification-udvidelsespunkt (plugin'en org.eclipse.ui.editors)

Annotationstypen er den nøgle, der skal bruges til at finde den tilhørende markeringsannotationsspecifikation. Annotationstyper kan udvide andre annotationstyper, og der er derfor også et implicit forhold mellem markeringsannotationsspecifikationer. En markeringsannotationsspecifikation for en given annotationstype færdiggøres af den markeringsannotationsspecifikation, som gives for supertyperne for den givne annotationstype. Markeringsannotationsspecifikationerne behøver derfor ikke være fuldstændige, som de gjorde før. AnnotationPreferences genkalder markeringsannotationsspecifikationerne. Ved hjælp af org.eclipse.ui.texteditor.AnnotationPreferenceLookup kan du hente en annotationsindstilling for en given annotationstype, som transparent færdiggør indstillingen langs annotationssupertypekæden.

Markeringsannotationsspecifikationer er udvidet med tre ekstra attributter for at gøre det muligt at definere et tilpasset udseende for en given annotationstype i den lodrette lineal. Attributterne er: "icon", "symbolicIcon", og "annotationImageProvider". Værdien for "icon" er stien til en fil, der indeholder ikonbilledet. Værdien af "symbolicIcon" kan være enten "error", "warning", "info", "task" eller "bookmark". Attributten "symbolicIcon" bruges til at fortælle platformen, at annotation skal vises med de samme billeder, som bruges af platformen til at vise henholdsvis fejl, advarsler, oplysninger, opgaver og bogmærker. Værdien af "annotationImageProvider" er en klasse, der implementerer org.eclipse.ui.texteditor.IAnnotationImageProvider, som gør det muligt at foretage en fuld tilpasning af annotationsfremvisningen.

Den lodrette lineal bruger den tilknyttede IAnnotationAccess/IAnnotationAccessExtension til at tegne annotationer. Den lodrette lineal kalder ikke længere Annotation.paint. Generelt formodes annotationer ikke længere at tegne sig selv. Metoderne "paint" og "getLayer" er blevet forældede, med henblik på at annotationer i sidste ende skal blive UI-uafhængige. DefaultMarkerAnnotationAccess fungerer som standardimplementering af IAnnotationAccess/IAnnotationAccessExtension. DefaultMarkerAnnotationAccess implementerer følgende strategi for tegning/maling af annotationer: Hvis en annotation implementerer IAnnotationPresentation, kaldes IAnnotationPresentation.paint. Hvis ikke, slås udbyderen af annotationsbilledet op i annotationsindstillingen. Udbyderen af annotationsbilledet er kun tilgængelig, hvis den er angivet, og hvis den plugin, der definerer den omsluttende markeringsannotationsspecifikation, allerede er indlæst. Hvis der er en udbyder af et annotationsbillede, videresendes kaldet til den. Hvis ikke, slås den angivne "icon" op. "symbolicIcon" bruges som endelig fallback. I forbindelse med tegning af annotationer er annotationspræsentationslaget relevant. DefaultMarkerAnnotationAccess slår præsentationslaget op ved hjælp af følgende strategi: Hvis annotationsindstillingen angiver et præsentationslag, bruges det angivne præsentationslag. Hvis der ikke er noget lag, og annotationen implementerer IAnnotationPresentation, bruges IAnnotationPresentation.getLayer, eller standardpræsentationslaget (som er 0) returneres.

Migrering til annotationTypes-udvidelsespunktet (plugin'en org.eclipse.ui.editors)

Følgende annotationstyper er erklæret af plugin'en org.eclipse.ui.editors:

   <extension point="org.eclipse.ui.editors.annotationTypes">
      <type
         name="org.eclipse.ui.workbench.texteditor.error"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="2">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.warning"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="1">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.info"
         markerType="org.eclipse.core.resources.problemmarker"
         markerSeverity="0">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.task"
         markerType="org.eclipse.core.resources.taskmarker">
      </type>
      <type
         name="org.eclipse.ui.workbench.texteditor.bookmark"
         markerType="org.eclipse.core.resources.bookmark">
      </type>
</extension>   

Den definerede markerAnnotationSpecification-udvidelse stiller ikke længere attributterne "markerType" og "markerSeverity" til rådighed. De definerer "symbolicIcon"-attributten med den relevante værdi. MarkerAnnotation.paint og MarkerAnnotation.getLayer kaldes derfor ikke længere, dvs. det har ingen betydning, hvis du tilsidesætter disse metoder. Berørte klienter skal implementere IAnnotationPresentation.

ILaunchConfigurationType (pakken org.eclipse.debug.core)

Med indførelsen af starttilstande, der kan udvides, i 3.0 kan der findes mere end én startdelegeret for en startkonfigurationstype. Versioner forud for 3.0 understøttede kun én startdelegeret pr. startkonfigurationstype. Metoden ILaunchConfigurationType.getDelegate() er nu forældet. Metoden getDelegate(String mode) skal bruges i stedet for at hente den startdelegerede for en bestemt starttilstand. Den forældede metode er ændret, så den returnerer den startdelegerede for run-tilstanden.

ILaunchConfigurationTab og ILaunchConfigurationTabGroup (pakken org.eclipse.debug.ui)

Startskillebladsgrupper og startskilleblade får ikke længere besked, når en start er afsluttet. Metoden launched(ILaunch) i grænsefladen ILaunchConfigurationTab og ILaunchConfigurationTabGroup er forældet og kaldes ikke længere. Det har altid været problematisk at være afhængig af denne metode i forbindelse med startfunktionen, fordi skilleblade kun findes, når start udføres fra startdialogboksen. Med indførelsen af baggrundsstart kan denne metode ikke længere kaldes, fordi startdialogboksen lukkes, før det startobjekt, der bliver resultatet, findes.

ILaunchConfigurationTab og AbstractLaunchConfigurationTab (pakken org.eclipse.debug.ui)

Der er tilføjet to metoder til grænsefladen ILaunchConfigurationTab - aktiveret og deaktiveret. Disse nye livscyklusmetoder kaldes, når nogen går ind på eller forlader et skilleblad. Eksisterende implementeringer af ILaunchConfigurationTab, som er underklasser til den abstrakte klasse, der stilles til rådighed af fejlfindings-plugin'en (AbstractLaunchConfigurationTab), er binært kompatible, fordi metoderne implementeres i den abstrakte klasse.

Tidligere blev beskeden initializeFrom sendt til et skilleblad, når det blev aktiveret, og beskeden performApply, når det blev deaktiveret. På den måde gjorde startkonfigurationsskillebladsstrukturen kommunikation mellem skilleblade mulig via en startkonfiguration (ved at opdatere konfigurationen med aktuelle attributværdier, når nogen forlod et skilleblad, og opdatere det skilleblad, nogen var gået ind på for nylig). Da mange skilleblade ikke kan kommunikere mellem skilleblade, kan dette være ineffektivt. Der var heller ingen måde at skelne mellem et skilleblad, der blev aktiveret, og et skilleblad, der viste en valgt startkonfiguration for første gang. Med de nyligt tilføjede metoder kan skillebladene skelne mellem aktivering og initialisering og deaktivering og lagring af aktuelle værdier.

Standardimplementeringen af aktiveret, som er stillet til rådighed af skillebladet abstrakt, kalder initializeFrom. Standardimplementeringen af deaktiveret kalder performApply. Skilleblade, der vil bruge den nye API, skal tilsidesætte disse metoder, hvis det er påkrævet. Generelt gælder det, at for skilleblade, der ikke udfører kommunikation mellem skilleblade, er den anbefalede måde at implementere disse metoder igen, så de intet gør.

launchConfigurationTabGroup-udvidelsespunkttype (pakken org.eclipse.debug.ui)

I tidligere versioner blev perspektivskiftet angivet i en startkonfiguration via startkonfigurationsattributterne ATTR_TARGET_DEBUG_PERSPECTIVE og ATTR_TARGET_RUN_PERSPECTIVE. Med tilføjelsen af starttilstande, der kan udvides, i 3.0, kan denne fremgangsmåde ikke længere skaleres. Perspektivskift angives nu på basis af startkonfigurationstype, pr. starttilstand som en startkonfigurationstype understøtter. API er tilføjet til DebugUITools for at angive og hente det perspektiv, der er tilknyttet en startkonfigurationstype for en bestemt starttilstand.

Derudover er der tilføjet et valgfrit launchMode-element til launchConfigurationTabGroup-udvidelsespunktet, som tillader en bidraget skillebladsgruppe at angive et standardperspektiv for en startkonfigurationsttype og -tilstand.

Fra Eclipse-brugergrænsefladen kan brugere redigere det perspektiv, der er tilknyttet med en startkonfigurationstype, ved at åbne startkonfigurationsdialogboksen og vælge en node for startkonfigurationstypen i træstrukturen (i stedet for en individuel konfiguration). Der vises et skilleblad, som tillader brugeren at angive et perspektiv sammen med hver understøttet starttilstand.

[kun JDT] IVMRunner (pakken org.eclipse.jdt.launching)

Der er tilføjet to metoder til klassen VMRunnerConfiguration for at understøtte indstilling og hentning af miljøvariable. Implementorer af IVMRunner skal kalde VMRunnerConfiguration.getEnvironment() og videregive miljøet til den udførte JVM. Klienter, som bruger DebugPlugin.exec(String[] cmdLine, File workingDirectory) kan gøre det ved i stedet at kalde DebugPlugin.exec(String[] cmdLine, File workingDirectory, String[] envp). Det er tilstrækkeligt blot at videresende resultatet fra getEnvironment().

[kun JDT] Klasserne VMRunnerConfiguration og Bootstrap (pakken org.eclipse.jdt.launching)

I tidligere versioner havde VMRunnerConfiguration én attribut til at beskrive en startsti (boot). Attributten er en samling af strenge, som skal angives i -Xbootclasspath-argumentet. Der er tilføjet tre nye attributter til VMRunnerConfiguration til understøttelse af JVM'er, som gør det muligt at tilføje til startstien. De nye metoder/attributter, der er tilføjet, er:

Den gamle attribut, getBootClassPath(), findes stadig og indeholder en fuldstændig sti, som svarer til stien for de tre nye attributter. VMRunners, som understøtter mulighederne på den nye startsti, skal udnytte de nye attributter.

[Kun JDT] Forbedret understøttelse til arbejdskopier (pakken org.eclipse.jdt.core)

Arbejdskopifunktionen for Java-modeller er ændret i 3.0, så den har betydeligt øget funktionalitet. Før 3.0 tillod Java-modellen oprettelse af individuelle arbejdskopier af kompileringsenheder. Der kunne laves ændringer til arbejdskopien, som senere blev committet. Der var understøttelse af en begrænset analyse af en arbejdskopi i sammenhæng med resten af Java-modellen. Der var dog ingen måde, hvorpå disse analyser kunne beskæftige sig med mere end én arbejdskopi ad gangen.

Med ændringerne i 3.0 er det muligt at oprette og administrere sæt af arbejdskopier af kompileringsenheder og at udføre analyse under tilstedeværelsen af alle arbejdskopier i et sæt. Det er f.eks. nu muligt for en klient som JDT-refactoring at oprette arbejdskopier til en eller flere kompileringsenheder, som klienten overvejer at ændre og derefter at opløse typereferencerne mellem arbejdskopierne. Tidligere kunne dette kun lade sig gøre, efter ændringerne af arbejdskopierne af kompileringsenhederne var committet.

API-ændringerne i Java-modellen øger den forbedrede understøttelse på to måder:

(1) Den funktionalitet, der tidligere fandtes i IWorkingCopy, og som blev overtaget af ICompilationUnit er konsolideret i ICompilationUnit. IWorkingCopy-grænsefladen blev kun brugt dette ene sted og var mere generel, end det var nødvendigt. Denne ændring forenkler API'et. IWorkingCopy er forældet. Andre steder i API'et, hvor IWorkingCopy bruges som parameter eller resultattype, er også forældede. API-erstatningsmetoderne nævner ICompilationUnit i stedet for IWorkingCopy.

(2) Grænsefladen IBufferFactory er udskiftet med WorkingCopyOwner. Den forbedrede understøttelse af arbejdskopier kræver, at der er en objekt, som ejer arbejdskopierne. IBufferFactory er den korrekte placering, men navnet beskriver ikke rigtigt, hvordan den ny arbejdskopimekanisme fungerer. WorkingCopyOwner er meget mere sigende. Derudover er WorkingCopyOwner erklæret som en abstrakt klasse snarere end en grænseflade, hvilket gør det muligt at begrebet en arbejdskopiejer kan udvikles senere. Den ene metode på IBufferFactory flytter til WorkingCopyOwner uden at blive påvirket. WorkingCopyOwner implementerer ikke IBufferFactory, for at gøre det klart at IBufferFactory tilhører fortiden. IBufferFactory er forældet. Andre steder i API'et, hvor IBufferFactory vises som en parameter eller resultattype, er også forældet. Erstatnings-API-metoderne nævner WorkingCopyOwner i stedet for IBufferFactory.

Disse ændringer bryder ikke den binære kompatibilitet.

I tilfælde af overførsel skal alle referencer til typen IWorkingCopy i stedet referere til ICompilationUnit. Den eneste implementering af IWorkingCopy implementerer også ICompilationUnit, hvilket betyder, at objekter af typen IWorkingCopy kan konverteres sikkert til ICompilationUnit.

En klasse, der implementerer IBufferFactory, skal erstattes med en underklasse af WorkingCopyOwner. Selvom WorkingCopyOwner ikke implementerer selve IBufferFactory, vil det være muligt at erklære underklassen til WorkingCopyOwner, som implementerer IBufferFactory, og på den måde skabe en bro mellem gammel og ny (IBufferFactory erklærer createBuffer(IOpenable), hvorimod WorkingCopyOwner erklærer createBuffer(ICompilationUnit); ICompilationUnit udvider IOpenable).

Fordi de ændringer, der involverer IWorkingCopy og IBufferFactory, griber ind i hinanden, anbefaler vi, at du beskæftiger dig med dem samtidig. Oplysningerne om forældelserne er som følger:

Omstrukturering af org.eclipse.help plug-in

Plugin'en org.eclipse.help, som tidligere indeholdt API'er og udvidelsespunkter, der bidrog med og udvidede hjælpen samt viste hjælpen, indeholder nu blot API'er og udvidelsespunkter, der bidrager med og giver adgang til hjælperessourcer. En del af standardhjælpen til UI-implementeringen, som var indeholdt i plugin'en, er flyttet til en ny plugin, org.eclipse.help.base, sammen med API'er til udvidelse af implementeringen. De API'er og udvidelsspunkter, som bidrager med hjælpe-UI'et og fremviser hjælpen, er flyttet til plugin'en org.eclipse.ui. Denne omstrukturering giver programmerne større fleksibilitet, hvad angår hjælpen. Med den nye struktur kan programmer, der er baseret på den generiske arbejdsbænk, levere deres egen hjælpe-UI og/eller hjælpeimplementering, eller de kan helt udelade hjælpen.

Da de berørte udvidelsespunkter og API-pakker kun er beregnet til brug for selve hjælpen, er det usandsynligt, at de eksisterende plugins påvirkes af denne ændring. De er kun inkluderet her for fuldstændighedens skyld:

Ny søge-UI-API

Det er i 3.0 tilføjet en ny API til implementering af tilpassede søgninger. Den oprindelige API er forældet i 3.0, og vi anbefaler, at klienter overføres til den nye API i pakkerne org.eclipse.search.ui og org.eclipse.search.ui.text.

Klienterne skal oprette implementeringer af ISearchQuery, ISearchResult og ISearchResultPage. ISearchResultPage-implementeringen skal derefter bidrage til det nye org.eclipse.search.searchResultViewPages-udvidelsespunkt.

Standardimplementeringerne til ISearchResult og ISearchResultPage leveres i pakken org.eclipse.search.ui.text.

null-meddelelser i MessageBox og DirectoryDialog (pakken org.eclipse.swt.widgets)

Før 3.0 ville kald til SWT's DirectoryDialog.setMessage(String-streng) eller MessageBox.setMessage(String-streng) med en null-værdi for strengen resultere i en dialogboks uden tekst i titellinjen. Denne funktionsmåde var ikke angivet (det har aldrig været tilladt at videresende null) og skabte problemer med getMessage, som ikke må returnere null. I 3.0 resulterer overførsel af null nu i en IllegalArgumentException-undtagelse, og angivelserne er ændret, så de angiver dette, hvilket bringer det på linje med metoden på deres superklasse Dialog.setMessage. Hvis du bruger Dialog.setMessage, skal du sikre, at den streng, der overføres, aldrig er null. Hvis du vil have en dialogboks uden tekst i titellinjen, skal du bare overføre en tom streng.

Forbedring af modal tilbagemelding på status

Understøttelse af samtidige funktioner kræver mere avancerede måder at vise modal status på. Som en del af indsatsen for at opnå en større lydhørhed, er der implementeret yderligere statussupport i klassen IProgressService. Den eksisterende måde at vise status på med ProgressMonitorDialog fungerer stadig. For at få en bedre brugeroplevelse anbefaler vi at skifte til den nye IProgressService.

Dokumentet Showing Modal Progress in Eclipse 3.0 beskriver, hvordan du skifter til den nye IProgressService.

Debug Action Groups er fjernet

Udvidelsespunktet Debug Action Groups (org.eclipse.debug.ui.debugActionGroups) er fjernet. I Eclipse 3.0 indførte arbejdsbænken understøttelse af aktiviteter via udvidelsespunktet org.eclipse.platform.ui.activities. Denne understøttelse leverer alt det, som Debug Action Groups leverede. Dertil kommer, at den er nemmere at bruge (den understøtter mønstre i stedet for at angive alle funktioner udtømmende), og understøttes via programmet af en API. Det giver ikke fejl, hvis du ikke får fjernet referencerne til det gamle udvidelsespunkt. Referencer til udvidelsespunktet ignoreres simpelthen. Produktleverandører opfordres til at bruge aktivitetsunderstøttelsen på arbejdsbænken til at tilknytte sprogspecifikke fejlfindingsfunktioner med sprogspecifikke aktiviteter, f.eks. kan C++-fejlfindingsfunktioner tilknyttes en aktivitet kaldet "Developing C++".

BreakpointManager kan deaktiveres

IBreakpointManager definerer nu metoderne setEnabled(boolean) og isEnabled(). Når breakpoint-styring er deaktiveret, skal fejlfindingsfunktionen ignorere alle registrerede breakpoints. Fejlfindingsplatformen leverer også en ny lyttemekanisme, IBreakpointManagerListener, som gør det muligt for klienter at blive registreret hos breakpoint-styringen, så de får besked, når aktiveringen ændres. Oversigten Breakpoints kalder denne API fra en ny aktiverings/deaktiveringsfunktion, som gør det muligt for brugeren at "springe over alle breakpoints". Fejlfindingsfunktioner, som ikke respekterer aktiveringen af breakpoint-styringen, vises som brudte, hvis brugeren forsøger at bruge denne funktion.

[Kun JDT] Deltagere i Java-søgning (pakken org.eclipse.jdt.core.search)

Sprog, der er tæt på Java, f.eks. JSP, SQLJ og JWS, skal kunne deltage i Java-søgningen. Implementorer af sådanne sprog skal især kunne:

En sådan implementor kaldes en deltagersøgning. Den udvider SearchParticipant-klassen. Deltagersøgningerne overføres til søgeforespørgsler (se SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)).

I forbindelse med indekserings- eller lokalisering af matcher skal en deltagersøgning definere en underklasse til SearchDocument, som kan hente indholdet af dokumentet ved at tilsidesætte enten getByteContents() eller getCharContents(). Der returneres en forekomst af denne underklasse i getDocument(String).

En deltagersøgning, som vil indeksere nogle dokumenter, bruger SearchParticipant.scheduleDocumentIndexing(SearchDocument, IPath) til at planlægge indekseringen af det givne dokument i det givne indeks. Når dokumentet er parat til at blive indekseret, kalder den underliggende struktur SearchParticipant.indexDocument(SearchDocument, IPath). Deltagersøgningen får så dokumentets indhold, analyserer det og tilføjer indeksindgange vha. SearchDocument.addIndexEntry(char[], char[]).

Når indekseringen er udført, kan man afsende forespørgsler til indekserne og finde matcher vha. SearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor). Den første beder vha. SearchParticipant.selectIndexes(SearchPattern, IJavaSearchScope) hver deltagersøgning om de indeks, der er nødvendige for at udføre forespørgslen. For hver indeksindgang, der matcher det givne mønster, oprettes et søgedokument ved at spørge deltagersøgningen (se getDocument(String)). Alle disse dokumenter overføres til deltagersøgningen, så den kan finde matcher vha. locateMatches(SearchDocument[], SearchPattern, IJavaSearchScope, SearchRequestor, IProgressMonitor). Deltagersøgningen giver besked til SearchRequestor vedrørende søgematcher vha. acceptSearchMatch(SearchMatch) og ved at overføre en forekomst af en underklasse af SearchMatch.

En deltagersøgning kan uddelegere en del af sit arbejde til standard-Java-deltagersøgningen. Du kan hente en forekomst af denne deltagersøgning vha. SearchEngine.getDefaultSearchParticipant(). En SQLJ-deltagersøgning kan f.eks., hvis den bliver bedt om at finde matcher, oprette .java-dokumenter fra sine .sqlj-dokumenter og uddelegere arbejdet til standarddeltagersøgningen ved at overføre .java-dokumenterne til den.