Avatar billede Slettet bruger
21. maj 2005 - 10:31 Der er 37 kommentarer og
1 løsning

Permission denied: cannot call non-public or static methods rem..

Hejsa,

Så er den gal igen :-)
Jeg sidder med noget remoting, der tilsyneladende endelig virker, i hvert fald hvis jeg bare returnerer en streng.

Jeg har en applikation, der er opdelt i 3 lag.

Fra grænsefladen kalder jeg en klasse remote (TestVare):

try
            {           
                ChannelServices.RegisterChannel(new TcpChannel());

                Funktionslag.TestVare tv = (TestVare)Activator.GetObject(typeof(TestVare), "tcp://localhost:5000/HentVare", null);
                label1.Text = tv.HentVare("Eco");
            }
            catch(Exception ex)
            {
                label1.Text = ex.ToString();
            }

TestVare-klassen her en metode:

public string HentVare(string varenavn)
        {
            string response = null;
           
            try
            {
                //ChannelServices.RegisterChannel(new TcpChannel());

                DataAccessLag.DbConnection conn = (DbConnection)Activator.GetObject(typeof(DbConnection), "tcp://localhost:5150/OpenConnection", null);
                BdpConnection connection = conn.OpenConnection();

                BdpCommand command = new BdpCommand();
                command.CommandText = "SELECT Varenavn FROM Varer WHERE Varenavn = '" + varenavn + "'";
                command.Connection = connection;

                BdpDataReader reader = command.ExecuteReader();
                while(reader.Read())
                {
                    response = reader.GetString(0);
                }
                reader.Close();
                command.Dispose();
            }
            catch(BdpException ex)
            {
                response = "Der kunne ikke oprettes forbindelse til databasen.";
                response += "Følgende fejl opstod:\n";
                response += ex.Message;
            }
           
            return response;
        }
    }

Denne klasse henter et connection-objekt fra et andet lag, der står for selve databasen:

public BdpConnection OpenConnection()
        {
            string dbNavn = "C:\\DolleNet_Remoting\\DataAccessLag\\DolleNet.IB";
           
            string connectionString =
                "Provider=interbase;" +
                "Assembly=Borland.Data.Interbase,Version=2.0.0.0;" +
                "Database=localhost:" + dbNavn + ";" +
                "UserName=sysdba;" +
                "Password=masterkey";

            connection = new BdpConnection(connectionString);

            try
            {
                connection.Open();
            }
            catch(BdpException ex)
            {
                throw ex;
            }
           
            return connection;
        }

Jeg får følgende fejl når jeg kører programmet:

System.Runtime.Remoting.RemotingException: Permission denied: cannot call non-public or static methods remotely.

Det sjove er, at jeg hvis jeg ændrer klassen TestVare, der kaldes fra grænsefladen til, bare at returnere en streng virker det fint og strengen udskrives fint i min label1.

Hvad er det jeg ikke har rettigheder til her?
Avatar billede Slettet bruger
21. maj 2005 - 10:36 #1
Det skal lige siges at jeg har ændret klassen "TestVare" til at have public fields, eller med andre ord har jeg ændret alle Bdp-objekterne til at blive oprettet som lokale objekter indenfor metoden, men det virker stadig ikke.
Før havde jeg lavet dem som private fields i toppen af klassen uden for metoden og regnede med at problemet skyldtes dette... Men nej.
Avatar billede burningice Nybegynder
21. maj 2005 - 11:20 #2
i hvilken linje får du fejlen? Du bruger jo remoting flere steder, så det er ikke så nemt at se
Avatar billede Slettet bruger
21. maj 2005 - 11:45 #3
Der står at det er i linie 40 i klassen TestVare.
Denne linie ser sådan ud:

command.Connection = connection;
Avatar billede Slettet bruger
21. maj 2005 - 11:49 #4
Hvis jeg ændrer min metode til:

public string HentVare(string varenavn)
        {
            string response = null;

            DataAccessLag.DbConnection conn = (DbConnection)Activator.GetObject(typeof(DbConnection), "tcp://localhost:5150/OpenConnection", null);
            BdpConnection connection = conn.OpenConnection();
           
            response = connection.State.ToString();
            return response;
        }

Får jeg en meddelelse tilbag til min windowsform, der siger "Open".
Avatar billede arne_v Ekspert
21. maj 2005 - 12:01 #5
det er umuligt at gennemskue hvad fejlen er - den fejl og den linie passer
ikke rigtigt sammen

jeg undrer mig iøvrigt over:

                BdpDataReader reader = command.ExecuteReader();
                while(reader.Read())
                {
                    response = reader.GetString(0);
                }

som gemmer første kolonne kun isdste række i response
Avatar billede Slettet bruger
21. maj 2005 - 12:04 #6
ArneV, metoden virker på den måde at én række hentes ud (kan kun være én vare med det medsendte navn) og lækkes i string response.
Metoden virker fint uden remoting, men med remoting får jeg fejlen som jeg skrev før.
Avatar billede Slettet bruger
21. maj 2005 - 12:09 #7
System.Runtime.Remoting.RemotingException: Permission denied: cannot call non-public or static methods remotely.

Server stack trace:
  at System.Runtime.Remoting.Channels.ChannelServices.DispatchMessage(IServerChannelSinkStack sinkStack, IMessage msg, IMessage& replyMsg)

Exception rethrown at [0]:
  at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
  at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
  at Borland.Data.Provider.BdpConnection.get_GetSQLConnection()
  at Borland.Data.Provider.BdpCommand.set_Connection(IDbConnection value)
  at Funktionslag.TestVare.HentVare(String varenavn) in c:\dollenet_remoting\funktionslag\testvare.cs:line 43
  at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
  at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

Af hvad jeg forstår ud fra denne fejl, er det command.Connection = connection; der forårsager fejlen (at Borland.Data.Provider.BdpCommand.set_Connection(IDbConnection value)).

Ved bare ikke hvad jeg skal gøre for at løse det.
Avatar billede Slettet bruger
21. maj 2005 - 12:30 #8
Ny definition på metoden HentVare() i klassen TestVare:

public string HentVare(string varenavn)
        {
            string response = null;
           
            try
            {
                string dbNavn = "C:\\DolleNet_Remoting\\DataAccessLag\\DolleNet.IB";
           
                string connectionString =
                    "Provider=interbase;" +
                    "Assembly=Borland.Data.Interbase,Version=2.0.0.0;" +
                    "Database=localhost:" + dbNavn + ";" +
                    "UserName=sysdba;" +
                    "Password=masterkey";
           
                BdpConnection connection = new BdpConnection(connectionString);
                connection.Open();

                BdpCommand command = new BdpCommand();
                command.CommandText = "SELECT Varenavn FROM Varer WHERE Varenavn = '" + varenavn + "'";
                command.Connection = connection;

                BdpDataReader reader = command.ExecuteReader();
                while(reader.Read())
                {
                    response = reader.GetString(0);
                }
                reader.Close();
                command.Dispose();
            }
            catch(BdpException ex)
            {
                response = "Der kunne ikke oprettes forbindelse til databasen.";
                response += "Følgende fejl opstod:\n";
                response += ex.Message;
            }

            return response;
        }

Returnerer fint det medsendte varenavn fra grænsefladen?!?
Det må da være noget med min connection, der åbenbart ikke kan kaldes remote af én elleranden årsag, eller i hvert fald ikke kan bruges som normalt.
Avatar billede arne_v Ekspert
21. maj 2005 - 12:36 #9
med kun 1 række plejer man at bruge if og ikke while
Avatar billede arne_v Ekspert
21. maj 2005 - 12:36 #10
Det lyder som om det er  BdpCommand og ikke TestVare du tilgår remote ??
Avatar billede Slettet bruger
21. maj 2005 - 12:37 #11
Sorry.
Det mener jeg også at jeg plejer, men fik af én eller anden grund en fejlmeddelelse med if og skiftede den fluks til while, hvorefter det kørte finno.
Avatar billede arne_v Ekspert
21. maj 2005 - 12:40 #12
rettelse:

er det

public BdpConnection OpenConnection()

du kalder remote ?

Det kan du ikke - en database connection er lokal.
Avatar billede Slettet bruger
21. maj 2005 - 12:40 #13
Ja måske. Kan det være fordi, at man ikke kan bruge en connection, der er kaldt via en anden klasse.
Det burde jo ikke virke på den måde, da det er klassen TestVare, der bruger den, men det virker lidt sådan alligevel.

Jeg får fek,s. ingen fejl hvis jeg udskriver connection.state og sender den med tilbage i response strengen.

Dette må jo betyde, at jeg får adgang til BdpConnection objektet, men at jeg åbenbart ikke har rettigheder til at bruge det sammen med min BdpCommand...
Avatar billede Slettet bruger
21. maj 2005 - 12:42 #14
Ok. Så er det jo der problemet ligger :-)
Vil det sige at jeg ikke kan lave en distribueret applikation, hvor databasen ligger på én server, brugergrænsefladen på en anden og dataklasserne på en tredje?

Så skal databasen jo ligge sammen med dataklasserne...?
Avatar billede arne_v Ekspert
21. maj 2005 - 12:44 #15
det kan du godt (omend performance sikkert vil være elendig)

men dine data klasser skal så returnere data objekter (dine data klasser,
array af dine data klasser, ArrayList af dine data klasser etc.) og connection
etc. skal holdes lokalt i data laget
Avatar billede burningice Nybegynder
21. maj 2005 - 13:15 #16
hvis du gerne vil have databasen til at ligge på sin egen server, hvorfor connecter du så ikke direkte til den over socekts? Nu ved jeg ikke hvilken database du bruger, men alle seriøse databaser understøtter denne mulighed, og på den måde kan du få en distribueret applikation hvor din database kan ligge hvorend i verden du har lyst.
Avatar billede Slettet bruger
21. maj 2005 - 13:28 #17
Kan du evt. komme med et eksempel hvordan man gør det?
Det lyder jo meget besnærende, men jeg kan ikke lige se for mig hvordan man gør dette.
Avatar billede arne_v Ekspert
21. maj 2005 - 13:33 #18
du retter vel bare localhost i din connectionString !?
Avatar billede Slettet bruger
21. maj 2005 - 13:42 #19
Retter den til hvad ArneV?
Undskylder hvis jeg spørger dumt, men vil det sige at hvis jeg specificerer en ip kører det så over sockets?
Avatar billede burningice Nybegynder
21. maj 2005 - 13:52 #20
som jeg skrev... nu ved jeg ikke hvilken database du bruger, så det er svært at sige... du kunne evt. være så flink at oplyse os det, så vi bedre kunne hjælpe dig ;)
Avatar billede Slettet bruger
21. maj 2005 - 13:54 #21
Interbase 7.1 :-)
Avatar billede burningice Nybegynder
21. maj 2005 - 14:05 #22
ja, så er det jo ikke nemt... det er jo en filbaseret database, ligesom f.eks. access.

Desværre. Så er du lidt på herrens mark på det område. Går ud fra det er noget firma-relateret hvor du ikke bare uden videre kan skifte til en anden database.
Avatar billede Slettet bruger
21. maj 2005 - 14:10 #23
Næsten. Det er et eksamensprojekt til skolen :-)
Hvad er problemet i at den er filbaseret? Ville det have været anderledes med MS sql eller MySql?
Avatar billede burningice Nybegynder
21. maj 2005 - 14:20 #24
problemet er... at den er filbaseret. Dvs. at man skal have filadgang til databasen, ergo skal programmet køre på samme computere som databasen, eller i det mindste have adgang til den via SMB.

Ja, det vil være meget anderledes med MSSQL eller MySQL da disse ikke er filbaseret, og tilgås via sockets. Altså er det underordnet om ens program kører på samme computer som databasen, eller på en håndholdt på månen. Så længe der er netforbindelse mellem computerne er den eneste forskel man vil opleve den forsinkelse der er at sende pakker frem og tilbage. Der vil ikke være samme overhead som f.eks. med .Net remoting med at serialisere og deserialisere hele tiden.
Avatar billede Slettet bruger
21. maj 2005 - 14:31 #25
Gutter. Lægger i lige et svar begge to så i kan få point?
Jeg håber det er i orden hvis ArneV hiver de 60 af dem, det var ham der fik mig på sporet med hensyn til connection-objektet, der kun kunne benyttes lokalt.
Avatar billede Slettet bruger
21. maj 2005 - 14:37 #26
Én lille ting mere.
ArneV. Hvad mente du med:

"men dine data klasser skal så returnere data objekter (dine data klasser,
array af dine data klasser, ArrayList af dine data klasser etc.) og connection
etc. skal holdes lokalt i data laget"?

Jeg spørger fordi jeg nu kører remoting på et par af mine klasser og at det virker fint med den ene, jeg kan godt oprette poster i databasen (varer), men jeg får en system.nullreferenceexception når jeg forsøger at trække poster ud fra et dataset, der er sendt med som ref parameter til en metode i én af de remote klasser.
Avatar billede Slettet bruger
21. maj 2005 - 14:42 #27
Min fejl. Havde glemt at den skulle have en ref sammen med parameter-værdien, så jeg forsøgte at hive poster ud af et tomt dataset.
Avatar billede arne_v Ekspert
21. maj 2005 - 14:43 #28
svar
Avatar billede arne_v Ekspert
21. maj 2005 - 14:44 #29
cf>

Er du sikker på at Interbase er en fil database ?

Jeg troede at det var en server (som lyttede på port 3050) !
Avatar billede Slettet bruger
21. maj 2005 - 15:00 #30
Det er vidst en server, men man skal registrere den enkelte database på serveren og henvise til selve filen. Så der er nok noget om det CyberFessor siger.
Avatar billede arne_v Ekspert
21. maj 2005 - 15:05 #31
Hvis den lytter på en port så bør den kunne tilgåes remote således at
databasen er remote men data access layer er lokal.
Avatar billede Slettet bruger
21. maj 2005 - 15:40 #32
Ok. Tak for hjælpen med remoting ArneV.
Jeg har valgt at jeg vil skrive om mine erfaringer med remoting, men at jeg ikke vil lave det i selve opgaven. Grunden er, at jeg nu efter at have fået metodekaldene til at virke, er støt ind i endnu et problem, nemlig at jeg ikke kan tilgå properties på objekterne grundet sikkerhedsmæssige årsager i .NET version 1.1.
Ved godt at der er en workaround, men har ikke tid til at få sat mig ind i det :-)
Avatar billede burningice Nybegynder
21. maj 2005 - 16:01 #33
arne>> kiggede på connectionstrings.com, samt borlands egen hjemmeside (http://community.borland.com/article/0,1410,27152,00.html) og alle ekspemlerne viser at man skal skrive stien til en fil, altså må den være filbaseret.
Avatar billede arne_v Ekspert
21. maj 2005 - 16:07 #34
hvis Microsoft havde valgt syntaxen:

SqlConnection con = new SqlConnection("server=MINPC;Integrated Security=SSPI;database=
C:\Program Files\Microsoft SQL Server\MSSQL\Data\master.mdf");

ville du så også kalde den fil baseret ?

Jeg tror at det er det som de mener med:

localhost:C:\noget.gdb
Avatar billede burningice Nybegynder
21. maj 2005 - 16:16 #35
hvis det var den eneste måde at koble sig på databasen, så vil den jo blive filbaseret, i og med at man ikke kan definere ip eller dns-navn på den computere filen skulle ligge på.

Men det kan da godt være man kan skrive

db.etdomain.dk:c:\noget.gdb

i så fald, så tager jeg mine ord i mig også, og må tilstå at interbase ikke er filbaseret (i den forstand at man skal have fysisk adgang til filen for at kunne bruge databasen)
Avatar billede arne_v Ekspert
21. maj 2005 - 16:19 #36
se også f.eks.

http://bdn.borland.com/article/0,1410,25843,00.html
http://bdn.borland.com/article/0,1410,32847,00.html
Avatar billede burningice Nybegynder
21. maj 2005 - 16:22 #37
*tager mine ord i mig*
Avatar billede arne_v Ekspert
21. maj 2005 - 16:24 #38
Remote access til Interbase er iøvrigt mest berygtet p.g.a. den her historie:

http://www.theregister.co.uk/2001/01/12/borland_interbase_backdoor_exposed/
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester