/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
Tvinge reload af klasse.
Fra : Janus


Dato : 04-04-01 23:33

Hvis en klasse bliver ændret / kompileret igen i Runtime, hvordan tvinger
man så jvm til at loade den igen, så ændringerne af klassen bliver
registreret i det program der instantierer den ?

Mvh Janus




 
 
Mogens Hansen (05-04-2001)
Kommentar
Fra : Mogens Hansen


Dato : 05-04-01 05:43


"Janus" <janus141@pop.k-net.dk> wrote in message
news:9ag7eh$i17$1@eising.k-net.dk...
> Hvis en klasse bliver ændret / kompileret igen i Runtime, hvordan tvinger
> man så jvm til at loade den igen, så ændringerne af klassen bliver
> registreret i det program der instantierer den ?
>

Jeg tror at du skal kigge på klassen "ClassLoader" i java.lang.object.
Måske bliver du nødt til at skrive din egen specialisering. Klassen har en
metode "loadClass" som vist kan gøre det du er ude efter.
Jeg har ikke selv prøvet det, men så det demonstreret for et år siden.

Venlig hilsen

Mogens Hansen



Dennis Thrysøe (05-04-2001)
Kommentar
Fra : Dennis Thrysøe


Dato : 05-04-01 07:20

Når det lykkes dig skal du være opmærksom på, at der kan opstå problemer.

Dels er det svært at håndtere hvis for eksempel en brugt metode
forsvinder. Dels er der en tendens til at hver ny-loadet klasse loades
af en ny ClassLoader, og dermed lever i sin egen isolerede verden i VM'en.

-dennis


Janus wrote:

> Hvis en klasse bliver ændret / kompileret igen i Runtime, hvordan tvinger
> man så jvm til at loade den igen, så ændringerne af klassen bliver
> registreret i det program der instantierer den ?
>
> Mvh Janus


Niels Bech Nielsen (05-04-2001)
Kommentar
Fra : Niels Bech Nielsen


Dato : 05-04-01 07:05

Hvis du har loaded den via SystemClassLoader'en kan du ikke aftvinge klassen
igen.

Lav din egen ClassLoader hvis du vil kunne hot deploy'e klasser

/Niels

"Janus" <janus141@pop.k-net.dk> skrev i en meddelelse
news:9ag7eh$i17$1@eising.k-net.dk...
> Hvis en klasse bliver ændret / kompileret igen i Runtime, hvordan tvinger
> man så jvm til at loade den igen, så ændringerne af klassen bliver
> registreret i det program der instantierer den ?
>
> Mvh Janus
>
>
>



Janus (05-04-2001)
Kommentar
Fra : Janus


Dato : 05-04-01 11:50

Jeg gør sådan:

Task ta = new Task();
....
ta.doTask(); // lad os sige, den returnerer tallet 1.
....
[Så bliver klassen CompileMe, der implementerer interfacet Task, slettet og
skrevet igen på harddisken, bare med et andet indhold, så doTask()
returnerer 2]
....
ta = new Task();
ta.doTask(); // den skal returnere 2, men returnerer 1



Heeelp me ! Jeg fatter ikke noget som helst af det med ClassLoader... jeg
får en Class som return type, hvad skal jeg bruge den til ? Jeg kan heller
ikke sige ta.getClassLoader() og jeg kan ikke lade ta extende Class, da det
er et interface... jeg ved SLET ikke, hvor jeg skal begynde, eller hvor jeg
skal begynde.
Jeg kan se, at jeg er ved at bevæge mig ud på et lidt avanceret plan, så det
er jo godt nok. Nu skal jeg også bare forstå, hvad det er, jeg er ved at
rode mig ud i.

Er der nogen, der kan hjælpe mig lidt her ?

Med venlig hilsen

Janus

"Niels Bech Nielsen" <nbn@logical.nospam.dk> wrote in message
news:lgmja9.ld.ln@java.logical.dk...
> Hvis du har loaded den via SystemClassLoader'en kan du ikke aftvinge
klassen
> igen.
>
> Lav din egen ClassLoader hvis du vil kunne hot deploy'e klasser
>
> /Niels
>
> "Janus" <janus141@pop.k-net.dk> skrev i en meddelelse
> news:9ag7eh$i17$1@eising.k-net.dk...
> > Hvis en klasse bliver ændret / kompileret igen i Runtime, hvordan
tvinger
> > man så jvm til at loade den igen, så ændringerne af klassen bliver
> > registreret i det program der instantierer den ?
> >
> > Mvh Janus
> >
> >
> >
>
>



Niels Bech Nielsen (06-04-2001)
Kommentar
Fra : Niels Bech Nielsen


Dato : 06-04-01 11:09


"Janus" <janus141.spam@pop.k-net.dk> skrev i en meddelelse
news:9ahik3$6ue$1@eising.k-net.dk...
> Jeg gør sådan:
> Task ta = new Task();
> ta.doTask(); // lad os sige, den returnerer tallet 1.
> [Så bliver klassen CompileMe, der implementerer interfacet Task, slettet
og
> skrevet igen på harddisken, bare med et andet indhold, så doTask()
> returnerer 2]
> ta = new Task();
> ta.doTask(); // den skal returnere 2, men returnerer 1

Hvis Task er et interface kan du ikke lave en new Task().

Jeg sidder her og bliver fuldstændig i tvivl om, hvad det overhovedet er, du
gerne vil lave? Er du sikker på, at du på at du vil dynamisk genloade den
samme klasse?

Jeg vil prøve hvis jeg får tid, at konstruere et kort eksempel på hvordan du
kan anvende ClassLoadere til at få dine klasser ind dynamisk.





Janus (06-04-2001)
Kommentar
Fra : Janus


Dato : 06-04-01 16:26

Det er klassen CompileMe, der implementerer interfacet Task, jeg
instantierer.
Det, jeg vil lave er, at klienten overfører en .java fil, som serveren
kompilerer og derefter eksekverer. Kompileringen kan ikke foregå på
klienten, da det skal være muligt for klienten at lave referencer til
objekter, han ikke har i sin besiddelse.
Denne proces skal så kunne gentages så mange som man lyster. Dvs. den .java
fil der overføres hedder det samme fra gang til gang, men indholdet er noget
andet. Eneste lighed, rent kodemæssigt, er, at der i .java filen står
"public class CompileMe implements Task" og at en metode defineret i
interfacet realiseres.

Håber, det er til at forstå.

Og på forhånd mange gange tak for hjælpen.

Mvh Janus


"Niels Bech Nielsen" <nbn@logical.nospam.dk> wrote in message
news:s4pma9.slm.ln@java.logical.dk...
>
> "Janus" <janus141.spam@pop.k-net.dk> skrev i en meddelelse
> news:9ahik3$6ue$1@eising.k-net.dk...
> > Jeg gør sådan:
> > Task ta = new Task();
> > ta.doTask(); // lad os sige, den returnerer tallet 1.
> > [Så bliver klassen CompileMe, der implementerer interfacet Task, slettet
> og
> > skrevet igen på harddisken, bare med et andet indhold, så doTask()
> > returnerer 2]
> > ta = new Task();
> > ta.doTask(); // den skal returnere 2, men returnerer 1
>
> Hvis Task er et interface kan du ikke lave en new Task().
>
> Jeg sidder her og bliver fuldstændig i tvivl om, hvad det overhovedet er,
du
> gerne vil lave? Er du sikker på, at du på at du vil dynamisk genloade den
> samme klasse?
>
> Jeg vil prøve hvis jeg får tid, at konstruere et kort eksempel på hvordan
du
> kan anvende ClassLoadere til at få dine klasser ind dynamisk.
>
>
>
>



Niels Bech Nielsen (07-04-2001)
Kommentar
Fra : Niels Bech Nielsen


Dato : 07-04-01 09:31

Der er lige 3 muligheder, som springer mig i øjnene.

1 Hvorfor få ren java kode over på din server (Husk på, at du sikkert kører
med en simpel security manager, der giver fuld adgang til system, filer,
netværk etc). Istedet
kan du medlevere et API med RMI stubbe til din server (Jeg tror nok, du
skrev noget om RMI på et tidspunkt), og dine server objekter er selvfølgelig
mappet over mod et interface, som du medleverer i koden. Hvis det er tredie
persons server eller program, bør du iøvrigt gøre vedkommende opmærksom på
denne risiko.

2 Hvis du er ivrig efter at få java kode derover, som implementerer et
interface, står det dig vel frit for at ændre navnet på klassen. Det er ikke
svært at lave en søg og erstat så CompileMe kommer til at hedde f.eks.
MyClass_354. Så har du bedre muligheder for at spore dig tilbage (da
CompileMe.java og CompileMe.class vil blive overskrevet hver gang). Du bør
som minimum logge remote socket addr, timestamp og sekvensnummeret på
klassen.

3 Endelig kan du som du har efterspurgt få loaded klassen med en nu
ClassLoader hver gang. Jeg poster et eksempel i dk.binaer (Subj:
SimpleClassLoader.java) . Jeg har compilet min klasse CompileMe, som
implementerer interfacet Task (med metoden doTask()). CompileMe skriver 1 ud
på skærmen i doTask. Denne blev compileret, og klassen blev i mit tilfælde
manuelt omdøbt til CompileMe1.class. Derudover lavede jeg en version 2
(CompileMe2.class), som skriver 2 ud på skærmen. Nu har jeg to udgaver af
CompileMe.

Klassen SimpleClassLoader bruger jeg til at loade mine særlige klasser med.
Bemærk, den er skrevet til JRE1.3. Her gælder, at en ClassLoader vil prøve
at loade klasser v.hj.a. den indbyggede classLoader først, og til sidst hvis
klassen ikke kunne genkendes kaldes findClass(String name) til at hente
klassen. Jeg har derfor placeret CompileMe klasserne i et underbibliotek,
som der ikke er classpath til, og derfor kaldes findClass.
Min private counter bruges bare til at loade de to versioner op sekventielt.
Bemærk, at når jeg henter en instans, tager jeg fat i en ny classloader, og
loader classen op. Derved "glemmes" den gamle classLoader og derfor den
gamle klasse definition. I main kan du også se, at t1 og t2 ikke har samme
klasse (Fordi de er loaded af hver sin ClassLoader).

Håber det giver dig lidt inspiration, men tænk dig for gud skyld om, og kig
evt. videre på security mekanismerne (Jeg er ikke så stiv i det selv), for
det er noget af en bagdør du kan komme til at åbne ubevidst.

/Niels Bech Nielsen -- Logical
SCJ2P - ** Sun Certified Java 2 Programmer **

"Janus" <janus141.spam@pop.k-net.dk> skrev i en meddelelse
news:9akn60$5p1$1@eising.k-net.dk...
> Det er klassen CompileMe, der implementerer interfacet Task, jeg
> instantierer.
> Det, jeg vil lave er, at klienten overfører en .java fil, som serveren
> kompilerer og derefter eksekverer. Kompileringen kan ikke foregå på
> klienten, da det skal være muligt for klienten at lave referencer til
> objekter, han ikke har i sin besiddelse.
> Denne proces skal så kunne gentages så mange som man lyster. Dvs. den
..java
> fil der overføres hedder det samme fra gang til gang, men indholdet er
noget
> andet. Eneste lighed, rent kodemæssigt, er, at der i .java filen står
> "public class CompileMe implements Task" og at en metode defineret i
> interfacet realiseres.
>
> Håber, det er til at forstå.
>
> Og på forhånd mange gange tak for hjælpen.
>
> Mvh Janus
>
>
> "Niels Bech Nielsen" <nbn@logical.nospam.dk> wrote in message
> news:s4pma9.slm.ln@java.logical.dk...
> >
> > "Janus" <janus141.spam@pop.k-net.dk> skrev i en meddelelse
> > news:9ahik3$6ue$1@eising.k-net.dk...
> > > Jeg gør sådan:
> > > Task ta = new Task();
> > > ta.doTask(); // lad os sige, den returnerer tallet 1.
> > > [Så bliver klassen CompileMe, der implementerer interfacet Task,
slettet
> > og
> > > skrevet igen på harddisken, bare med et andet indhold, så doTask()
> > > returnerer 2]
> > > ta = new Task();
> > > ta.doTask(); // den skal returnere 2, men returnerer 1
> >
> > Hvis Task er et interface kan du ikke lave en new Task().
> >
> > Jeg sidder her og bliver fuldstændig i tvivl om, hvad det overhovedet
er,
> du
> > gerne vil lave? Er du sikker på, at du på at du vil dynamisk genloade
den
> > samme klasse?
> >
> > Jeg vil prøve hvis jeg får tid, at konstruere et kort eksempel på
hvordan
> du
> > kan anvende ClassLoadere til at få dine klasser ind dynamisk.
> >
> >
> >
> >
>
>



Allan Unnerup (05-04-2001)
Kommentar
Fra : Allan Unnerup


Dato : 05-04-01 12:07

>Hvis en klasse bliver ændret / kompileret igen i Runtime, hvordan tvinger
>man så jvm til at loade den igen, så ændringerne af klassen bliver
>registreret i det program der instantierer den ?

Web-serverne har forskellig måde at gøre det på.

Eksempel:

Java Web Server fra SUN skal lukkes ned og op igen for at tvinge ændringerne
igennem.

Resin-serveren gør det automatisk. Du skal bare oploade den nye klasse, så
bliver den automatisk benyttet næste gang den kaldes.

Hilsen Allan



Janus (05-04-2001)
Kommentar
Fra : Janus


Dato : 05-04-01 12:22

Dette her er en application, ikke jsp... godt nok foregår noget af det over
RMI, men mit problem er lokalt på serveren.

VH Janus

"Allan Unnerup" <alu@eogs.dk> wrote in message
news:9ahjre$clo$1@news.inet.tele.dk...
> >Hvis en klasse bliver ændret / kompileret igen i Runtime, hvordan tvinger
> >man så jvm til at loade den igen, så ændringerne af klassen bliver
> >registreret i det program der instantierer den ?
>
> Web-serverne har forskellig måde at gøre det på.
>
> Eksempel:
>
> Java Web Server fra SUN skal lukkes ned og op igen for at tvinge
ændringerne
> igennem.
>
> Resin-serveren gør det automatisk. Du skal bare oploade den nye klasse, så
> bliver den automatisk benyttet næste gang den kaldes.
>
> Hilsen Allan
>
>



Dennis Thrysøe (05-04-2001)
Kommentar
Fra : Dennis Thrysøe


Dato : 05-04-01 12:42

> Resin-serveren gør det automatisk. Du skal bare oploade den nye klasse, så
> bliver den automatisk benyttet næste gang den kaldes.

Bare af nysgerrighed: Hvordan håndteres følgende så i Resin?

Samlinger af objekter der er instanser af forskellige udgaver af den
samme klasse?

F.eks. en Vector med en masse Foo objekter. Foo opdateres, og
overskrives. Der laves en ny Foo som kommer i samme Vector.


-dennis


Niels Bech Nielsen (06-04-2001)
Kommentar
Fra : Niels Bech Nielsen


Dato : 06-04-01 11:07

Det jeg har set fra Weblogic håndterer hot-deployment på følgende måde:

Hot-deployment kan kun ske fra særlige ClassLoadere, som hvis klassen skal
være unik. Når der kommer ændringer i klasserne droppes ClassLoaderen, og en
ny loades op med de nye klasser. Det betyder at alle gamle refererede
klasser "hænger fast" i den gamle ClassLoader. Det er indtil videre løst med
et skuldertræk - bare ærgeligt.

/Niels



"Dennis Thrysøe" <qabi@qabi.dk> skrev i en meddelelse
news:3ACC5A12.5050309@qabi.dk...
> > Resin-serveren gør det automatisk. Du skal bare oploade den nye klasse,

> > bliver den automatisk benyttet næste gang den kaldes.
>
> Bare af nysgerrighed: Hvordan håndteres følgende så i Resin?
>
> Samlinger af objekter der er instanser af forskellige udgaver af den
> samme klasse?
>
> F.eks. en Vector med en masse Foo objekter. Foo opdateres, og
> overskrives. Der laves en ny Foo som kommer i samme Vector.
>
>
> -dennis
>



Søg
Reklame
Statistik
Spørgsmål : 177552
Tips : 31968
Nyheder : 719565
Indlæg : 6408847
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste