URL-typer i Java. Hva er en classloader? Kompilert Java-kode er i et plattform-uavhengig format (en class-fil). Et Java-program er ikke én eksekverbar.

Slides:



Advertisements
Liknende presentasjoner
12.Studienreise nach Finnland,
Advertisements

Kvinner og politikk Kvinnelig valgmobilisering i Nord-Norge: Glasstak eller etterslep? Marcus Buck.
Repetisjon innkapsling static tabell av primitiv datatype LC191D Videregående programmering Høgskolen i Sør-Trøndelag, Avdeling for informatikk og e-læring.
Tabeller av objekter Klassen ArrayList
Design av sikre web-applikasjoner
14 okt. 2003, Arne Maus Inst. for informatikk, UiO
C++ for Java-programmerere
Datafiler og serialisering Tekstfiler Scanner-klassen Binær overføring av data Direkte tilgang til filinnholdet Serialisering LC191D Videregående programmering.
Bygningsdelstabellen
Teknologi for et bedre samfunn 1 Asbjørn Følstad, SINTEF Det Digitale Trøndelag (DDT) Brukervennlig digitalisering av offentlig sektor.
Uke 10 - Sortering, og hvordan lage en klasse for et klassebibliotek 21 okt. 2003, Arne Maus Inst. for informatikk, UiO.
Kontrollstrukturer (Kapittel 3)
1 Litt om OO og programmering Arne Maus. 2 OO og Java (og C++, C#)  Arven fra Simula  Programstruktur i Java  Generering av objekter  Beskyttelse.
Programmering i Java versjon januar 2005 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else.
Fôr til oppdrettstorsk – bruk av vegetabilsk feitt Odd Leknes Forskningsdagene 2007 Alta.
Erfaringer etter innføring av Mantoux i helsestasjonene og skolehelsetjenesten Evaluering: Bruker 3 x mer tid i testsituasjonen. Vanskeligere å sette på.
Fra forelesningene om involveringspedagogikk Et utviklingsarbeid Philip Dammen Manuset er under arbeid.
IS-102 Klassedefinisjoner
Kapittel 14 Simulering.
Tema: Introduksjon Hvorfor Velocity? Installasjon Velocity VS. JSF / JSP Eksempler Oppsumering.
C# for javaprogrammerere
Aksess kontroll None shall pass.
Generelt I/O if/else Funksjoner Lists Løkker Dictionaries Annet Listebehandling Klasser Python med noen algdat-anvendelser Åsmund Eldhuset asmunde *at*
Foreløpige tall pr Randi Sæther
Feilhåndtering. Feil er uunngåelige! Erfaring viser at feil i dataprogrammer som består av mer enn noen få linjer ikke er til å unngå. For å få et godt.
Fag LO189D - Objektorientert programmering Objektorientert programmering© Else Lervik, TISIP - HiST/IDB vår-99Leksjon 11 Applet’s Hva karakteriserer applet’sside.
Jæger: Robuste og sikre systemer INF150 Programmering torsdag 31.8 Kapittel 3: Grunnlag for programmering i Visual Basic.
Kap 06 Diskrete stokastiske variable
Objekt Orientert Programmering (OOP). Objektorientering (OO)1/6 Objektorientering er en grunnleggende måte å organisere komplekse fenomener på.
Web-applikasjoner Prosjekt3 Logging Gruppe 9 Malik Muhammad Naeem Kevan Qureshi.
Innherred samkommune 1 Årsrapport og Regnskap 2007 Samkommunestyret 10. april 2008 Administrasjonssjef Ola Stene.
Programmering i Java versjon desember 2002 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else.
Programmering i Java versjon august 2004 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else.
Programmering i Java versjon Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik.
Programmering i Java versjon Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik.
Programmering i Java versjon Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else Lervik.
Programmering i Java versjon desember 2002 Kun til bruk i tilknytning til læreboka ”Programmering i Java” skrevet av Else.
1 Arrayer og form(ularer) (Kapittel 4). 2 Mål  Forstå assosiative og superglobale arrays  Kunne behandle webformularer (forms)  Kjenne forskjellen.
Høgskolen i Oslo Web-programmering Feilhåndtering i PHP.
Intro til php - Uke3.2 - Ronny Mandal Introduksjon til PHP.
Dynamiske nettsider PHP Del 1 – variable. PHP  PHP (Personal Home Page)  Fritt tilgjengelig programmeringsspråk  åpen kildekode  Plattformuavhengig.
PARLAY/OSA Referanser: Referanser Foredraget er i all hovedsak basert på to artikler. Disse kan finnes på:
Eiendomsmeglerbransjens boligprisstatistikk Februar 2011 Norges Eiendomsmeglerforbund og Eiendomsmeglerforetakenes Forening ECON Poyry og FINN.
Andre funksjoner. Her kommer en beskrivelse av søkefunksjoner, knapper og annen funksjonalitet. 2.
Fra forelesningene om involveringspedagogikk Et utviklingsarbeid Philip Dammen Manuset er under arbeid.
ESøknad - Et webbasert system for elektronisk innlevering av søknader om forskningsmidler Kort presentasjon av systemet beregnet på prosjektledere/forskere.
NM i prototyping - Yggdrasil 2014
Bankenes sikringsfond Revisjonskontoret
Virksomhetsrapport Oktober Innhold 1. Oppsummering 2. Hovedmål 3. Pasient 5. Aktivitet 4. Bemanning 6. Økonomi 7. Klinikker 2.
1 Kap 06 Ordnede / Sorterte lister Oppgave nr 06_02 Polynomer Klassehierarki Javadokumentasjon.
Å lese tall fra en fil, klassen Scanner 1.Et Scanner-objekt kan knyttes til et strømobjekt eller til en streng. 2.Kan skanne teksten etter data av ulike.
To accompany Quantitative Analysis for Management, 8e by Render/Stair/Hanna 15-1 © 2003 by Prentice Hall, Inc. Upper Saddle River, NJ Kapittel 15.
Elevundersøkelsen ( ) UtvalgGjennomføringInviterteBesvarteSvarprosentPrikketData oppdatert 7. trinnVår , Symbolet (-) betyr.
Tabeller Dette er en tabell, eller array. Den kan defineres sånn som dette: public int[] heltallsTabell = new int[11]; //Her er 11 tabellens lengde for.
1 Java Database Connectivity (JDBC) Norvald H. Ryeng
 Udgangspunkt Hovedkonto 0-6 Fratrukket -Forsyning -Tjenestemands- pension forsyning -Overførsler -Forsyning -Tjenestemands-
INF1000 (Uke 14) Resten av eksamen H03 + del av V05 Grunnkurs i programmering Institutt for Informatikk Universitet i Oslo Are Magnus Bruaset og Anja B.
Veivalgsanalyse etter Sørlandsmesterskapet i lang (klassisk) distanse 2004.
Main metoden n public static void main(String[] args){ } n Inni denne metoden skjer alt! n Det kan bare finnes en main metode per program. n Den kan ligge.
INF Objektorientert programmering
Tidsregistrering v/HiST DATAGRUNNLAG: Evaluering av HiST; en spørreskjemaundersøkelse blant Forskerforbundets medlemmer høsten 2009 v/HiST.
Object  Klassen i java  Alle klasser arver fra denne om ikke noe annet blir spesifisert  ArrayList.add(Object instans)  Alle elementer formes til Object.
Ekstra mange tips til Oblig 3! 12. mars 2007 Are Magnus Bruaset og Arild Waaler Inst. for informatikk, UiO.
INF1000 (Uke 14) Eksamen V06 Grunnkurs i programmering Institutt for Informatikk Universitet i Oslo Are Magnus Bruaset og Arild Waaler.
Byggeklosser i java  Klassedefinisjon  Variabel deklarasjon  Metodedeklarasjoner  En ordentlig klasse  Spesielle/kryptiske skrivemåter  løkker og.
Protokoller Pensum: Olsen, kap. 5 og 6. Kommunikasjonsprotokoll Rutiner for å administrere og kontrollere oversending av data Telefonsamtale (”Hallo”,
Inf1000 (Uke 10) HashMap og ArrayList
INF1000 (Uke 4) Mer om forgreninger, While-løkker
XML og JDOM Helge Furuseth XML  XML = Extensible Markup Language Basert på SGML – Standard Generalized Markup Language  HTML =
Kapittel 10 Exceptions Handtering av exceptions Ein exception er eit objekt som representerer ein feil eller eit unntak Exceptions blir kasta av.
Utskrift av presentasjonen:

URL-typer i Java

Hva er en classloader? Kompilert Java-kode er i et plattform-uavhengig format (en class-fil). Et Java-program er ikke én eksekverbar fil, men består av mange class-filer. Class-filer lastes på forespørsel fra programmet. Classloaderen er det objektet som er ansvarlig for utføring av denne jobben.

Standard classloading-struktur i J2SE Bootstrap classloader | Standard extensions classloader | System classloader | Network classloader

Lasting av typer Alle typer må forstås navngitt i to faser: Lokasjon + Typenavn Fullt kvalifisert typenavn: foo.Bar Lokasjon: c:\java\myclasses\ Lokasjon: c:\java\myclasses.jar Fordeler: -Enkelt å skrive henvisninger da navnene blir relativt korte. -Ikke behov for rekompilering da man endrer miljøvariabelen CLASSPATH til å henvise til riktig lokasjon (eventuelt benytter extensions).

Bakgrunn for problemstilling Alfa sender en melding til Bravo som sier at Bravo skal laste en klasse Help. Bravo er avhengig av at lokasjonen til denne typen er inkludert i en av dens aktuelle classloadere. Alfa er ikke sikker på at dette er tilfelle, og sender derfor lokasjonen først, og deretter typen som skal lastes.

Alfa.main() Socket s = new Socket(hostname, port); PrintWriter w = new PrintWriter(s.getOutputStream(),true); w.println("u Help"); w.close(); s.close();

Bravo.interpret() URLClassLoader ucl = null; String[] lines = input.split("#"); for(int i=0; i<lines.length; i++){ char command = lines[i].charAt(0); String param = lines[i].split(" ")[1]; if(command == 'u'){ ucl = new URLClassLoader(new URL[]{new URL(param)}); }else if(command == 'l'){ Class clas = null; if(ucl != null)clas = ucl.loadClass(param); else clas = Class.forName(param); Object o = clas.newInstance(); }

Help (ver.1) Denne versjonen refererer til core API klassene: java.lang.System java.io.PrintStream java.lang.String public class Help{ public Help(){ System.out.println(”Instance created”); }

Help (ver.2) Denne versjonen refererer til klassene: java.lang.System java.io.PrintStream java.lang.String equipment.Radio ( public class Help{ public Help(){ equipment.Radio.sendSOS(); System.out.println(”Instance created and SOS sent”); }

Oppsummering Konseptet med den underforståtte bruken av CLASSPATH + typenavn i en situasjon der adaptive programmer skal utveksle kommandoer og tilpasse seg hverandre, dekker ikke alle behov. Forutsetningen om at programmereren kan sette CLASSPATH når det trengs, er ikke lenger levedyktig. Det blir nødvendig å uttrykke typehenvisninger som inneholder navn og informasjon om lokasjon.

Løsning: Innføre URL-typer En URL-type inneholder navn og lokasjon. r = new equipment.Radio(); Målet med en slik løsning er å gjøre CLASSPATH-informasjon overflødig.

Krav I: Flyttbarhet Ved representasjon av URL-typer i class-filen er det viktig at man forholder seg til JVM- spesifikasjonen, slik at flyttbarheten blir sikret. Til tross for at man benytter URL-typer i en classloader-struktur som ikke er modifisert, er det krav om at det skal være mulig å laste og kjøre refererende typer.

Class-filen: Generelt Inneholder definisjonen av én klasse eller interface. En gyldig representasjon av en klasse eller et interface uavhengig av form. Inneholder en strøm av 8-bit bytes JVM-spesifikasjonen, bruke typenavnene u1, u2 og u4 for å representere henholdsvis unsigned en-, to-, eller fire-byte kvantiteter. (En signed byte har verdiområde fra En bit benyttes til å indikere hvorvidt tallet er positivt eller ikke. En unsigned byte har derimot verdiområde fra 0-255, ingen bit benyttes for å indikere fortegn.)

Class-filen: Struktur Det er ikke mulig å direkte adressere dens elementer. Enkelte strukturer har ikke faste størrelser, men holder selv orden på sine lengder. For å lese informasjon fra slutten av class- filen, må den traverseres rekursivt.

Class-filen: Struktur ClassFile{ u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constants_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; }

public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello World!"); } ca fe ba be d 0a f 09 Êþº¾ a c 69 6e e () f f 4c 69 6e 65 4e V...Code...LineN 75 6d c d umberTable...mai 6e b 4c 6a f 6c 61 6e 67 n...([Ljava/lang 2f e 67 3b a 53 6f 75 /String;)V...Sou c f c 6c 6f 57 rceFile...HelloW 6f 72 6c 64 2e 6a c orld.java c c c 6c 6f Hello W 6f 72 6c a 0c 00 1b 00 1c a orld! c 6c 6f 57 6f 72 6c a HelloWorld...jav 61 2f 6c 61 6e 67 2f 4f 62 6a a/lang/Object... 6a f 6c 61 6e 67 2f d java/lang/System f c 6a f 69...out...Ljava/i 6f 2f e d 3b o/PrintStream; a f 69 6f 2f e java/io/PrintSt d e 74 6c 6e ream...println c 6a f 6c 61 6e 67 2f (Ljava/lang/Str 69 6e 67 3b ing;)V.! d a b b *·..± a b 00 0c % b b b ²....¶..± a a d e

Opprinnelig løsningsstrategi: Kodete URL-navn Et gyldig typenavn er bygd opp av bokstaver og sifre, samt tegnene ’_’ og ’$’. Dersom en CONSTANT_Class_info henviser til et ugyldig navn, vil java.lang.ClassFormatError kastes.

Class-filen: Attributter JVM-spesifikasjonen definerer flere forskjellige attributter. JVM-implementasjon må ignorere alle attributter den ikke gjenkjenner. –Dette gjør det mulig å definere nye attributter for å støtte leverandør-spesifikk debugging, eventuelt å pakke utvidet informasjon inn i class-filen.

URLType_attribute URLType_attribute{ u2 attribute_name_index; u4 attribute_length; u2 typename_ index; u2 location_index; } attribute_name_index -> CONSTANT_Utf8_info = ’URLType’ Attribute_length = 4 typename_index -> CONSTANT_Utf8_info = … location_index -> CONSTANT_Utf8_info = …

Fullt kvalifisert typenavn: Foo Lokasjonsinformasjon, som er ca fe ba be a f 09 Êþº¾ a c 69 6e e () f f 4c 69 6e 65 4e V...Code...LineN 75 6d c d umberTable...mai 6e b 4c 6a f 6c 61 6e 67 n...([Ljava/lang 2f e 67 3b a 53 6f 75 /String;)V...Sou c f c 6c 6f 57 rceFile...HelloW 6f 72 6c 64 2e 6a c orld.java c c c 6c 6f Hello W 6f 72 6c a 0c 00 1b 00 1c a orld! c 6c 6f 57 6f 72 6c a HelloWorld...jav 61 2f 6c 61 6e 67 2f 4f 62 6a a/lang/Object... 6a f 6c 61 6e 67 2f d java/lang/System f c 6a f 69...out...Ljava/i 6f 2f e d 3b o/PrintStream; a f 69 6f 2f e java/io/PrintSt d e 74 6c 6e ream...println c 6a f 6c 61 6e 67 2f (Ljava/lang/Str 69 6e 67 3b c ing;)V...URLType f 6f d a 2f 2f...Foo e e 6f f 66 6f 6f e 6a ar.jar.! d a b b *·..± a b 00 0c % b b b ²....¶..± a a d e 00 1d e 00 1f....

Egenskrevet bytekode-manipulator Fordeler med egenskrevet løsning: Kan skalere løsningen etter oppgaven Størrelse på ca. 2-4% av BCEL og Javassist Raskere enn BCEL og Javassist da enkelte interne struktures ignoreres

Egenskrevet bytekode-manipulator Ved testing av prototypen viste løsningen seg å være tregere enn BCEL og Javassist. Flaskehalsen var følgende kode: int length = input.readUnsignedShort(); byte[] bytes = new byte[length]; input.read(bytes); value = new String(bytes, "UTF-8"); Den ble byttet med: value = input.readUTF()

Krav II: Særegne versjoner Hvis man forener dynamisk lasting og et ikke-forgrenet classloading-design, vil ikke navneunikhet være tilstrekkelig. SAAPP Alfa bes laste: – – ClassB refererer til en gammel versjon av ClassC. Når den symbolske referansen fra ClassB skal oppklares, viser det seg imidlertid at ClassA har kommet ClassB i forkjøpet med å laste en nyere versjon av ClassC. Den refererte typen ligger da i namespace og Alfa vil få denne returnert ved oppklaring.

Web-tjeneren Tomcat Løsning som omgår standard foreldre-barn delegerings policy: Bootstrap | System | Common / \ Catalina Shared / \ Webapp1 Webapp2...

Modifisert modell Bootstrap | Extensions | System | Common / \ SAAPP1 SAAPP2...

Egenskaper til løsningsstrategi Typer som er tilgjengelig gjennom system classloader og overliggende classloadere vil være endelige. En SAAPP vil ikke kunne få lastet sin særegne versjon av en type dersom en annen versjon er tilgjengelig gjennom system classloader eller overliggende classloadere. Dette gjør at man må være bevisst på hvilke class-filer man gjør tilgjengelig gjennom CLASSPATH eller extensions classloader. Common har lokasjoner til typer som skal gjøres tilgjengelig for alle underliggende classloadere og som hver underliggende classloader skal ha mulighet til å laste sin egen versjon av.

Krav III: Fellesgjøring Alfa har mottatt melding fra DBs agent: the Text = new Alfa vil hente tilsvarende informasjon fra VG: Text()); I uttrykket ovenfor castes objektet som returneres fra ”the Text()” til Text. JVM identifiserer en type med dens fullt kvalifiserte navn, samt tilhørende classloader. I uttrykket ovenfor må instansen av Text som det castes til, være lastet av samme classloader som objektet ”the Text()” henviser til, hvis ikke vil ClassCastException kastes.

Identifisering av typer JVM identifiserer en klasse med dens fullt kvalifiserte navn, samt tilhørende classloader. Dette betyr at to classloadere kan laste samme type, men ved sammenligning vil disse regnes som ulike. Typisk kode som vil fremprovosere en feilsituasjon: MyClassLoader mcl = new MyClassLoader(); Class clas = mcl.loadClass(”Foo”); Object object = clas.newInstance(); Foo foo=(Foo)object;

Testscenario oppsett 1/3 To meldinger fra forskjellige avsendere blir sendt til Alfa. Den første meldingen ber om at en type ved navn TMP1 skal lastes. Dette er en klasse som skal simulere resultatet av kompilering av en mottatt melding. Den eksekverer følgende kodelinje i konstruktøren: ClassA a = new ClassA(); Den andre meldingen henviser til TMP2, som wrapper følgende kodelinje: ClassB b = new ClassB(); Begge TMP-klassene er modifisert med informasjon om URL-typer.

Testscenario oppsett 2/3 ClassA oppretter et objekt av ClassC i konstruktøren, og legger en beskjed inn i det. Videre registreres objektet av ClassC i rammeverket, slik at det kan deles med andre SAAPP’er. public ClassA(){ //the commonC = new ClassC(); ClassC c = new ClassC(); c.setString("This message is set by: " +this); ObjectMediatorX.addObject(this, new ReferenceWrapper(ClassC.class, "sharedC", null),c); }

Testscenario oppsett 3/3 ClassB vil på sin side hente ut det innlagte ClassC objektet fra rammeverket. public ClassB(){ try { ClassC c = (ClassC)(ObjectMediatorX.invokeRef(this, new ReferenceWrapper(ClassC.class, "sharedC", null))); } catch (Exception e) {} }

Testscenario suksesskriterier ClassB må hente ut det samme objektet av ClassC, sharedC, som ClassA la inn i rammeverket. Dette har rammeverket ansvar for. For at ClassB skal kunne bruke objektet som rammeverket returnerer, må det castes til ClassC. For å unngå feil ved castingprosessen, må classloaderen som laster ClassC ved eksekvering av ClassB sin kode, være den samme som lastet ClassC ved eksekvering av ClassA sin kode. Dette har classloader-strukturen ansvar for.

Løsningsstrategi: Skille mellom URL-typer og vanlige typer Når man uttrykker lokasjon i en URL-type, er man som programmerer mer spesifikk og i en viss grad overstyrende i forhold til hvordan egne og andres program skal hente typen. En vanlig type vil virke som en type hvis opphav er åpent. Den vil være ubestemt i forhold til hvor den skal lastes fra. Som programmerer vil man overlate til applikasjonen å finne frem til typen som skal benyttes. Dersom typen tas i bruk i en applikasjon hvor den opprinnelige programmereren ikke har kontroll over tilgjengelige lokasjoner, vil den åpne referansen kunne føre til bruk av en allerede lastet type med oppgitt navn.

Hva er en URL-type? En URL-type består av lokasjon og fullt kvalifisert typenavn. Det er ikke en statisk tilstand. En type deklareres ikke i sin egen kildekode som en URL-type, men tilstanden bestemmes av konteksten. Det er en situasjonsbestemt tilstand som gis av refererende type. Dersom en type refererer til Foo, og har informasjon om lokasjonen til Foo, er Foo i dette tilfellet en URL-type.

URLTypeClassLoader Innfører én classloader per URL. Fordeler: To agenter vil kunne spesifisere at de skal bruke samme versjon av en type for å kunne utveksle informasjon. Ved casting imellom objektene til disse to agentene vil det ikke oppstå ClassCastException da typen i begge tilfeller lastes fra samme classloader. Vil være mulig at én agent kan bruke forskjellige versjoner av samme type. Dette krever imidlertid at deres refererende typer lastes i forskjellige classloadere. Dersom en agent har flere lokasjoner å laste fra, er det mulig at riktig versjon ikke lastes dersom man bare bruker én classloader per samtalepartner. Tilfeller hvor dette kan oppstå er når forskjellige versjoner av typen er tilgjengelig på flere enn én av URL'ene i URL-lista. Da vil URL'en som først ble lagt til bli benyttet. Denne muligheten for feil vil ikke være tilstede med den nye løsningsstrategien.

URLTypeClassLoader.loadClass() Class c = findLoadedClass(name); if(c == null){ try{ c = findSystemClass(name); }catch(ClassNotFoundException e1){ URLTypeClassLoader cl = (URLTypeClassLoader)urlTypes.get(name); if(cl != null) c = cl.loadClassLocally(name); else{ String pkgname = getPkgName(name); cl = (URLTypeClassLoader)urlPackages.get(pkgname); if(cl != null) c = cl.loadClassLocally(name); else{ Package pkg = findPackage(pkgname); if(pkg != null) c = findClass(name); else{ try{ c = delegator.loadClass(name, this); }catch(ClassNotFoundException e2){ c = findClass(name); }

CLDelegator.loadClass() public Class loadClass(String name, URLTypeClassLoader classloader)throws ClassNotFoundException{ Class clas = common.getLoadedClass(name); if(clas == null){ Enumeration cls = classloaders.elements(); while(cls.hasMoreElements()){ URLTypeClassLoader cl = (URLTypeClassLoader)cls.nextElement(); if(cl != classloader) clas = cl.getLoadedClass(name); if(clas != null)return clas; } if(classloader != common){ try{ return common.loadClassLocally(name); }catch(ClassNotFoundException e1){ return classloader.loadClassLocally(name); } return null; }

Modell av classloading-struktur Bootstrap | Extensions | System | Common / | | \ SAAPP1 URL1 URL2 SAAPP2...

Problemer / begrensinger Ikke mulig å isolere typer fra andre aktører. Problemer med pakketilgang grunnet runtime-packages. Bryter med innført foreldre-barn delegerings-policy. Classloaderen er avhengig av CLDelegator for å fungere Strukturen er ”låst”.