PDA

View Full Version : [JAVA] Permessi di accesso a file in Vista


franksisca
06-06-2009, 16:50
allora...ho finito la mia bella applicazione che lavora con i file, ma qualndo al eseguo (post offuscamento) su XP tutto bene, su Vista NO, ovvero non mi salva i file.

credo(suppongo, visto che non ho sorgenti e non posso verificare) che sia un problema di accesso ai file.

se è così qualcuno può suggerirmi su come risolverlo?
grazieeeee


P.S.: è possibile cambiare icona al mio jar??? (intendo l'icona che appare sul desk non quella in altro a sinistra :D)

fero86
06-06-2009, 22:37
"hai finito la tua bella applicazione" e "non ne hai i sorgenti per verificare"? :mbe:

comunque, nel caso si trattasse effettivamente di problemi di permessi su file, queste sono le domande cruciali:
1) devi distribuire la tua applicazione? se no basta che cambi i permessi sul tuo PC.
2) per quale motivo stai cercando di scrivere in cartelle dove non puoi scrivere? i permessi dei files e delle directories su Vista non é che siano impostati a culo.

franksisca
07-06-2009, 09:51
"hai finito la tua bella applicazione" e "non ne hai i sorgenti per verificare"? :mbe:

si...semplicemente perchè ho i sorgenti a cosenza e ora sono a rossano (fino a domani) :p

quindi la domanda è per mettere le mani avanti, così domani arrivo e sò cosa cercare :D


1) devi distribuire la tua applicazione? se no basta che cambi i permessi sul tuo PC.
si ovvio altrimenti non avrei chiesto

2) per quale motivo stai cercando di scrivere in cartelle dove non puoi scrivere? i permessi dei files e delle directories su Vista non é che siano impostati a culo.

cerco di scrivere in file che ho creato io:

con un installer io creo la struttura ad albero del mio programma, e poi all'interno di queste cartelle faccio delle operazioni.
una delle operazioni è "scrivere sul file".
quindi le cartelle non sono quelle di sistema (non voglio distruggere niente X_X) ma sono delle sottocartelle "mie".

ora che ci penso però...posso avviare il programma da console e vedere se genera qualche errore.

a volte mi perdo in un bicchiere mezzopieno d'acqua :p

fero86
07-06-2009, 20:47
si...semplicemente perchè ho i sorgenti a cosenza e ora sono a rossano (fino a domani) :p usa Live Mesh (https://www.mesh.com/welcome/default.aspx) :D


cerco di scrivere in file che ho creato io:

con un installer io creo la struttura ad albero del mio programma, e poi all'interno di queste cartelle faccio delle operazioni.
una delle operazioni è "scrivere sul file".
quindi le cartelle non sono quelle di sistema (non voglio distruggere niente X_X) ma sono delle sottocartelle "mie". cosa in linea di principio sbagliatissima: queste porcate si fanno su Linux, su Windows per motivi di sicurezza le cartelle %APPDATA% stanno da tutt'altra parte rispetto alle cartelle di installazione dei programmi in Program Files e hanno anche una configurazione di sicurezza del tutto diversa; il fatto che Java non ti permetta di sapere dove si trova la cartella %APPDATA% é ovviamente uno dei motivi per cui Java sucks.

comunque solitamente la soluzione a questo fastidiosissimo problema di Java consiste semplicemente nell'installare il programma in una cartella su cui hai pieno accesso, per esempio una sottocartella dei documenti.

franksisca
07-06-2009, 20:50
usa Live Mesh (https://www.mesh.com/welcome/default.aspx) :D

non sò cosa sia O_O
cosa in linea di principio sbagliatissima: queste porcate si fanno su Linux, su Windows per motivi di sicurezza le cartelle %APPDATA% stanno da tutt'altra parte rispetto alle cartelle di installazione dei programmi in Program Files e hanno anche una configurazione di sicurezza del tutto diversa; il fatto che Java non ti permetta di sapere dove si trova la cartella %APPDATA% é ovviamente uno dei motivi per cui Java sucks.

comunque solitamente la soluzione a questo fastidiosissimo problema di Java consiste semplicemente nell'installare il programma in una cartella su cui hai pieno accesso, per esempio una sottocartella dei documenti.

ok, proverò a salvarlo su Documenti

franksisca
09-06-2009, 16:07
allora, sono qui per "cercare" la soluzione (per vista per il momento...poi mi installo seven e vediamo).


il problema è questo:

java.io.FileNotFoundException: data\cliente.ktm (Accesso negato)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at saving.ArchivioClienti.salvaClienti(Unknown Source)
at saving.ArchivioClienti.caricaClienti(Unknown Source)
at graphic.I.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown
Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)


come supponevo il problema è di accesso ai file.
la mia domanda è....basta che quei file che utilizzo li salvo in "C:\dcocumenti\programmamio\miofile" oppure c'è qualche soluzione più elegeante?

RaouL_BennetH
09-06-2009, 16:45
Domandina scema :p

Se hai creato un installer, su Vista, non è che ti basterebbe lanciarlo con esegui come amministratore ?!?

franksisca
09-06-2009, 17:06
Domandina scema :p

Se hai creato un installer, su Vista, non è che ti basterebbe lanciarlo con esegui come amministratore ?!?

boh...non ci capisco niente...e non ho un pc conqvista qui...quindi quando lo provo su vista non ho il sorgente..e quando ho il sorgente non ho vista -.-

franksisca
18-07-2009, 15:07
ho aperto un thread ma avevo scordato di avere questo.


comunqu sono stesso problema :D

PGI-Bis
18-07-2009, 15:21
il fatto che Java non ti permetta di sapere dove si trova la cartella %APPDATA% é ovviamente uno dei motivi per cui Java sucks.

Per uno che sa usare Java trovare la cartella APPDATA è difficile quanto tagliarsi le unghie.

franksisca
18-07-2009, 15:32
Per uno che sa usare Java trovare la cartella APPDATA è difficile quanto tagliarsi le unghie.

ora dimmi quanto ridi se ti dico che ho le unghie dei piedi incarniti per problemi avvenuti al taglio???

PGI-Bis
18-07-2009, 15:44
Due parole: metodo nativo.

franksisca
18-07-2009, 16:14
Due parole: metodo nativo.

ok, mai usati.

cerco su google qualcosa al riguardo, se nel frattempo puoi indirizzarmi tu...

PGI-Bis
18-07-2009, 17:26
Premetto che non conosco nulla delle API di windows e il fatto che io sia riuscito ad ottenere il percorso di APPDIR in 5 minuti netti da una misura della difficoltà del problema.

Uno va a guardare come si fa ad ottenere la cartella APPDIR nelle API di Windows e, stando a google, risultano quattro linee di codice C/C++:

ITEMIDLIST* list;
char appdir[500];
SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &list);
SHGetPathFromIDList(list, appdir);

A questo punto appdir contiene la cartella APPDATA.

Ora, Java ha questo straordinario e apparentemente ignoto pezzo di sè chiamato JNI. Diciamo che vogliamo copiare appdir in uno StringBuilder. Giusto per vedere. Bene, supponendo che questo StringBuilder sia creato in Java ci troviamo con;

jobject stringBuilder; //lo StringBuilder: tutti i reference JNI sono jobject salvo un paio

Diciamo che vogliamo riempire lo stringBuilder un carattere alla volta. StringBuilder ha il metodo append(char). Usiamo questo. Prima prendiamo il metodo:

jclass stringBuilderClass = env->FindClass("java/lang/StringBuilder");
jmethodID appendChar = env->GetMethodID(stringBuilderClass, "append", "(C)Ljava/lang/StringBuilder;");

poi lo invochiamo. Vogliamo dire "per ogni carattere in appdir finchè ce ne sono stringBuilder.append(c)?". Scriviamo:

for(int i = 0; (i < 500) & (appdir[i] != '\0'); i++) {
env->CallVoidMethod(stringBuilder, appendChar, appdir[i]);
}

"env" è un puntatore JNIEnv che ottieni automaticamente da JNI quando realizzi un metodo nativo.

Questo tanto per dare un'idea dell'invocazione di metodi e di come appaiono gli oggetti JNI.

Passiamo al nostro problema.

Voglio ottenere la cartella "APPDATA".

1. Creo una classe Java con un metodo nativo (i nomi sono arbitrari):

package it.tukano.winapi;

public class WinApi {

public native String getAppDir();
}

Compilo:

javac -d . *.java

Poi creo l'header JNI:

javah it.tukano.winapi.WinApi

L'header contiene il prototipo della funzione JNI che rappresenta la controparte nativa di getAppDir, cioè la funzione che sarà invocata ogni volta che io dirò:

winApi.getAppDir();

Il prototipo è un po' strano a vedersi ma è al 99% convenzionale. L'unica cosa da notare è che il metodo nativo getAppDir() è senza argomenti e restituisce uno String, la controparte nativa restituisce un jstring e ha due argomenti. JNIEnv è il puntatore alle funzioni globali di JNI, jobject è un riferimento al "this" dell'invocazione Java.

Comunque la definizione di quella funzione è brevissima:

//file dllmain.cpp
#include "it_tukano_winapi_WinApi.h"
#include <shlobj.h>

JNIEXPORT jstring JNICALL Java_it_tukano_winapi_WinApi_getAppDir
(JNIEnv *env, jobject obj)
{
int SIZE = 500;
char buffer[SIZE];
ITEMIDLIST* list;
SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &list);
SHGetPathFromIDList(list, buffer);
return env->NewStringUTF(buffer);
}



NewStringUTF è una funzione JNI che dato un buffer di char restituisce una nuova stringa java (che in JNI è un jstring).

Compilando con il tuo ide c++ottieni la tua dll. Per usare il tuo WinApi dirai:

public class Main {

public static void main(String[] args) {
System.loadLibrary("winapi");
it.tukano.winapi.WinApi winApi = new it.tukano.winapi.WinApi();
System.out.println(winApi.getAppDir());
}
}

Sono 28 linee di codice, prova inclusa.

franksisca
18-07-2009, 18:17
asd....grazie mille.


provo e vi faccio sapere :D

fero86
19-07-2009, 11:40
Due parole: metodo nativo. c'é sempre il dubbio che un'intera DLL sia overkilling per chiamare una sola API; la possibilitá che esiste in C# di invocare direttamente l'API ad esempio toglierebbe l'imbarazzo.

tra l'altro un programmatore che sappia usare Java raramente sa usare anche il C++ e men che mai le API Win32, di conseguenza il problema non é cosi semplice come tagliarsi le unghie, specialmente se per risolverlo ricorre a chissá quali minchiate trovate su Google; il tuo codice ad esempio é semi-delirante, avresti dovuto scrivere una cosa del genere:

CHAR szBuffer[MAX_PATH];
HRESULT hr = SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szBuffer);
if (FAILED(hr) || (hr == S_FALSE))
{
// gestire l'errore
}

PGI-Bis
19-07-2009, 14:38
Ho incollato la prima cosa che ho trovato, premettendo a bella posta che non conosco le API di windows. Se io dovessi fare qualcosa di specifico per Windows probabilmente mi prenderei un bel libro e me lo leggerei. Ma google va benissimo: in effetti verificando su MSDN si sarebbe scoperto che la funzione che ho trovato io è stata sostituita da SHGetFolderLocation.

Io sono dell'idea che un programmatore per il fatto di essere tale debba essere in grado di usare C++ esattamente quanto è in grado di usare Java o un qualsiasi altro linguaggio.

Altrimenti resti lì in mutande ogni volta che non trovi una funzione nelle api standard, il che è francamente inaccettabile.

Una libreria dinamica per una funzione non è più eccessivo che cambiare interamente piattaforma per quell'unica funzione. Specialmente se l'alternativa è C#.

franksisca
19-07-2009, 16:32
allora, ho fatot le seguenti cose:

1) scaricato devc++
2) creato il file java
package it.tucano.winapi;


public class WinApi {

public native String getAppDir();
}

3) generato tramite javah il file it_tucano_winapi_WinApi.h
4) aperto devc++ e creato un nuovo progetto ddl
5) nuovo file cpp chiamato dllmain.cpp
6) copiato il codice di pgi

//file dllmain.cpp

#include "it_tucano_winapi_WinApi.h"
#include <shlobj.h>

JNIEXPORT jstring JNICALL Java_it_tucano_winapi_WinApi_getAppDir
(JNIEnv *env, jobject obj)
{
int SIZE = 500;
char buffer[SIZE];
ITEMIDLIST* list;
SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &list);
SHGetPathFromIDList(list, buffer);
return env->NewStringUTF(buffer);
}

(provo questo "per ora" e poi quello di fero86)
7) compilo con dev e mi dà questo errore:
Compilatore: Default compiler
Building Makefile: "C:\Dev-Cpp\Makefile.win"
Esecuzione di make...
make.exe -f "C:\Dev-Cpp\Makefile.win" all
g++.exe -c dllmain.cpp -o dllmain.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" -DBUILDING_DLL=1

In file included from dllmain.cpp:3:
it_tucano_winapi_WinApi.h:2:17: jni.h: No such file or directory
In file included from dllmain.cpp:3:
it_tucano_winapi_WinApi.h:15: error: `JNIEXPORT' does not name a type

dllmain.cpp:6: error: `JNIEXPORT' does not name a type

make.exe: *** [dllmain.o] Error 1

Esecuzione terminata



se ho capito bene il file generato da me (it_tucano_winapi_WinApi.h) non si collega alla libreria jni.h

la mia domanda è: dove trovo questa libreria?

franksisca
19-07-2009, 16:40
questa parte risolta cosìPima di compilare la nostra libreria occorre impostare i parametri del compilatore perchè trovi "jni.h".
L'header "jni" si trova nel jdk, cartella "include". Con dev-cpp la cosa si risolve così:

menu "strumenti"->"opzioni di compilazione". Nella finestra che compare seleziona la scheda "cartelle" quindi la scheda

"include C". Sopra il bottone "cancella invalida" c'è un pulsante che permette di selezionare una cartella del sistema.

Premilo e trova la cartella "c:\j2sdk1.4.2\include". Selezionala e poi premi "aggiungi". Fai lo stesso con la cartella

"c:\j2sdk1.4.2\include\win32". La posizione della cartella può cambiare a seconda dell'installazione del JDK presente sul tuo sistema operativo.

A questo punto non resta che lasciar compilare la libreria a Dev-cpp.

continuo e vi aggiorno

fero86
20-07-2009, 14:19
Ho incollato la prima cosa che ho trovato, premettendo a bella posta che non conosco le API di windows. Se io dovessi fare qualcosa di specifico per Windows probabilmente mi prenderei un bel libro e me lo leggerei. Ma google va benissimo: in effetti verificando su MSDN si sarebbe scoperto che la funzione che ho trovato io è stata sostituita da SHGetFolderLocation. non serve urlare la tua ignoranza, é sufficiente non palesarla in principio. non era quello l'unico motivo di semi-delirio nel codice che hai riportato: hai usato male le stringhe, infatti hai passato un vettore di char ad un parametro di tipo LPTSTR e le due cose sono equivalenti solo se non definisci la macro UNICODE prima di includere windows.h, che peró nelle versioni recenti di Visual C++ viene definita di default in molti templates di progetti tramite opzione al compilatore.
inoltre, essendo tu un programmatore Java e non C++, non sei abituato all'idea di dover liberare le risorse che allochi e quindi non hai chiamato la CoTaskMemFree per liberare il puntatore restituito da SHGetSpecialFolderLocation (si, un leak :) bravissimo!).

ripeto che per un programmatore che sa usare Java non é necessariamente* una questione di pochi secondi evitare di creare la solita applicazione ottusa che mette i dati nel suo stesso ramo di directories e quindi non é compatibile con Vista e futuri, mentre invece lo sarebbe se Java offrisse un modo semplice per conoscere i well-known path del sistema senza scendere a livello nativo.

* "non necessariamente" nel senso che esistono anche programmatori contemporaneamente esperti in Java e C++, e questi invece si spera che siano in grado.


Io sono dell'idea che un programmatore per il fatto di essere tale debba essere in grado di usare C++ esattamente quanto è in grado di usare Java o un qualsiasi altro linguaggio. l'onniscienza non esiste; tant'é che io non sono nemmeno sicuro di aver scritto bene "onniscienza".


Una libreria dinamica per una funzione non è più eccessivo che cambiare interamente piattaforma per quell'unica funzione. un conto é cambiare piattaforma e ricominciare da zero un progetto ormai al 99% e un conto é scegliere la piattaforma giusta per quel progetto fin dall'inizio. la migliore integrazione di .NET con Windows mi sembra un'ottima ragione per evitare Java se sai che il tuo programma girerá solo su Windows (altrimenti detto: non scriverei mai in Java un programma che deve girare solo su Windows).
io non é che posso mettermi a scrivere una DLL JNI tutte le volte che devo fare un programma Java che deve girare anche su Windows (perché poi come la mettiamo quando il programma deve girare non solo su Windows? non prendiamoci in giro, la libreria nativa per un compito cosi idiota é un giro della Madonna, anche come curva d'apprendimento non c'é paragone con un'alternativa piu semplice come un metodo o una property che restituiscono il path richiesto).


Specialmente se l'alternativa è C#. spiritoso, hai voglia di darmi un'altra volta ragione per sfinimento? :asd:

banryu79
20-07-2009, 14:51
Beh fero86,
condivido il tuo punto di vista sul discorso percui in Java (inteso come piattaforma di sviluppo) la mancanza di utlity comode come potrebbe essere quella che ti restituisce il path nel sistema locale della %APPDATA% e ti costringe a trovare "un'escamotage" per raggiungere quel path tramite, nel caso di Java, la tecnologia JNI e quindi la creazione di una dll che ti fa da ponte con il sistema operativo, sia overkill in confronto ad una chiamata a metodo di una libreria.

C'è anche da dire però, a voler mettere i puntini sulle "i", che è comunque fattibile, e non dipende dal linguaggio, quanto dalla piattaforma, che a differenza del citato C# che si appoggia a librerie create dagli stessi autori del sistema operativo su cui può girare, con tutti i fichissimi binding alle WinAPI (e vorrei anche vedere), Java non nasce di suo per lavorare specificatamente con Windows (anche se sicuramente i binding a metodi messi a disposizine nel JDK standard che ti permettano di accedere a variabili di ambiente well known come %APPDATA% in Windows possono benissimo essere implementati).

Percui quando fai un'affermazione di questo tipo:

il fatto che Java non ti permetta di sapere dove si trova la cartella %APPDATA% é ovviamente uno dei motivi per cui Java sucks

per me è poco circostanziata, ovvero i motivi per cui Java sucks (così come tutti gli altri linguaggi, ognuno con i suoi sucks, chi più chi meno) sono altri, non di certo questo (che ripeto, non ha niente a che vedere con il linguaggio in se).

malocchio
20-07-2009, 15:24
Scusatemi una cosa, ma una soluzione così non funziona o è troppo stupida?echo %appdata%Non mi sembra che ci siano grosse difficoltà nell'eseguire questo comando e salvarne l'output, o no?
Ho appena provato ed effettivamente dal terminale mi stampa correttamente il percorso completo della cartella "Dati Applicazioni" :read:

PGI-Bis
20-07-2009, 16:09
fero86, se l'idea di dover fare una libreria dinamica per windows ti spaventa così tanto vedrai che leggendo qua:

http://java.sun.com/docs/books/jni/html/jniTOC.html

e facendo riferimento a questo:

http://msdn.microsoft.com/en-us/library/aa139672.aspx

anche tu sarai in grado di farlo.

malocchio
21-07-2009, 11:30
Qualcuno sa dirmi se la soluzione che ho postato 2 post fa è fattibile? :mc:

RaouL_BennetH
21-07-2009, 11:51
Qualcuno sa dirmi se la soluzione che ho postato 2 post fa è fattibile? :mc:

L'ho provata io e mi restituisce correttamente la directory.

Ho provato anche la soluzione di PGI-Bis ma ho qualche problemino legato a Windows Vista ed ai permessi in lettura/scrittura su alcune directory.

RaouL.

banryu79
21-07-2009, 11:59
Qualcuno sa dirmi se la soluzione che ho postato 2 post fa è fattibile? :mc:
Beh, per essere fattibile è fattibile, ad esempio, con un accrocchio: scrivi un file bat che lancia il comando echo. Dalla applicazione lanci il processo cmd.exe con l'opportuno parametro per evitarne la vsualizzazione a video, e gli passi il bat da eseguire; mappi lo standard output e standard error in opportuni stream; e nello stream che mappa lo standard output trovi appunto l'output del comando echo.

Non è il massimo della vita però...

malocchio
21-07-2009, 14:07
Beh, per essere fattibile è fattibile, ad esempio, con un accrocchio: scrivi un file bat che lancia il comando echo. Dalla applicazione lanci il processo cmd.exe con l'opportuno parametro per evitarne la vsualizzazione a video, e gli passi il bat da eseguire; mappi lo standard output e standard error in opportuni stream; e nello stream che mappa lo standard output trovi appunto l'output del comando echo.

Non è il massimo della vita però...

Siete insaziabili però :D:D
Penso si possa fare anche senza file .bat

PGI-Bis
21-07-2009, 15:08
E' un'alternativa valida. Tra l'esecuzione di un processo esterno e il metodo nativo cambiano alcuni presupposti ma in definitiva si tratta in ambedue i casi di accedere ad una funzione non definita nella piattaforma standard.

franksisca
21-07-2009, 15:23
E' un'alternativa valida. Tra l'esecuzione di un processo esterno e il metodo nativo cambiano alcuni presupposti ma in definitiva si tratta in ambedue i casi di accedere ad una funzione non definita nella piattaforma standard.

am sono in previsino nelle prossime implemnentazioni???

tipo la gestione della tray è stata inserita....in futuro faranno anche l'accesso a queste caratteristiche???

PGI-Bis
21-07-2009, 15:47
Direi di no. Tieni conto che la piattaforma Java è comunque pensata per l'uso su più sistemi operativi. La barra delle notifiche si è diffusa su tutti i desktop manager e la piattaforma Java ha recepito questa diffusione. L'opportunità di avere un unica cartella destinata ad ospitare i dati delle applicazioni presenti sul sistema non è assolutamente pacifica. In generale ci sono due "filosofie" riguardanti l'installazione di applicazioni desktop, quella di chi ritiene che un'applicazione debba essere assolutamente portabile e che quindi rigetta la distribuzione di parti del programma al di fuori di un'unica directory e quella di chi ritiene che un'applicazione deva integrarsi nel sistema ospite e che pertanto non solo ammette ma richiede l'accesso alle specifiche proprietà di sistema che, ad esempio, identificano la posizione che devono avere certi file.

Personalmente aderisco alla prima ritenendo che distribuire un programma a terzi sia come essere invitati in casa d'altri: se ti fanno accomodare in salotto non significa che sei autorizzato a ficcare il naso nel ripostiglio.

franksisca
21-07-2009, 16:10
Direi di no. Tieni conto che la piattaforma Java è comunque pensata per l'uso su più sistemi operativi. La barra delle notifiche si è diffusa su tutti i desktop manager e la piattaforma Java ha recepito questa diffusione. L'opportunità di avere un unica cartella destinata ad ospitare i dati delle applicazioni presenti sul sistema non è assolutamente pacifica. In generale ci sono due "filosofie" riguardanti l'installazione di applicazioni desktop, quella di chi ritiene che un'applicazione debba essere assolutamente portabile e che quindi rigetta la distribuzione di parti del programma al di fuori di un'unica directory e quella di chi ritiene che un'applicazione deva integrarsi nel sistema ospite e che pertanto non solo ammette ma richiede l'accesso alle specifiche proprietà di sistema che, ad esempio, identificano la posizione che devono avere certi file.

Personalmente aderisco alla prima ritenendo che distribuire un programma a terzi sia come essere invitati in casa d'altri: se ti fanno accomodare in salotto non significa che sei autorizzato a ficcare il naso nel ripostiglio.
ok, anche io la penso come te propendendo per la prima, ovvero non mi devo adattare a ovunque vada altrimenti non userei java.

ma come si risolve "in genere" il problema degli utenti con permesssi limitati?

soprattutto in ambiente win...visto che "tipicamente" se all'utente linux gli si dice come cambiare i permessi di accesso ad un file è sicuramente più pratico du un utente win. (tipicamente non vuol dire sicuramente)

RaouL_BennetH
21-07-2009, 16:24
ok, anche io la penso come te propendendo per la prima, ovvero non mi devo adattare a ovunque vada altrimenti non userei java.

ma come si risolve "in genere" il problema degli utenti con permesssi limitati?

soprattutto in ambiente win...visto che "tipicamente" se all'utente linux gli si dice come cambiare i permessi di accesso ad un file è sicuramente più pratico du un utente win. (tipicamente non vuol dire sicuramente)

Secondo me potresti anche 'rigirarti' la domanda:

Perchè devo avere permessi particolari per far girare la mia applicazione ?

Indipendentemente dal so, credo che sia meglio pensare a monte di prevedere un qualsiasi tipo di account.

PGI-Bis
21-07-2009, 16:29
Per un'applicazione portabile la limitazione dei permessi è irrilevante. L'unica cartella che esiste è quella in cui l'utente ha copiato l'eseguibile del programma azione che richiede necessariamente il permesso di gestire quella cartella.

Se per funzionare il programma ha bisogno di altre cartelle allora non è più un'applicazione portabile e occorre seguire le linee guida del sistema operativo.

Tieni conto che le librerie standard consentono di verificare i permessi di accesso ai file e di cambiarli se necessario. Tuttavia se un utente non ha il permesso di scrittura su un file è difficile che abbia il "permesso di modificare i permessi".

franksisca
21-07-2009, 19:06
ok, allora vi riiro l'altra domanda.

come faccio io, che uso dei file per salvarmi elenco clienti e altre cosa, ad "impacchettartli" nel jar stesso?

così come per le immagini???

inoltre, la dll che ho creato, è possibile metterla nel jar e non doverla mettere allo stesso livello.

si magari sono domande niubbe, ma non ho mai fatto applicazioni che dovessero girare all'esterno di eclipse, quindi sono argomenti totalemtne nuovi per me :D

PGI-Bis
21-07-2009, 19:31
Le librerie dinamiche devono essere estratte perchè il contenuto del jar non è parte dei percorsi di ricerca delle librerie dinamiche. Puoi distribuirle col jar ed estrarle dinamicamente oppure puoi semplicemente distribuire la tua applicazione come archivio zip. A conti fatti è la stessa cosa solo che lasci l'estrazione all'utente. Lo stesso vale per le immagini anche se normalmente queste sono incluse nel jar insieme a tutte le risorse "statiche".

Per quanto riguarda il come bisogna vedere l'ide. Ad esempio in Netbeans ci sono dei percorsi che il cui contenuto è automaticamente incluso nel jar (tipicamente ciò che è contenuto in src che non sia un file .java). Credo che Eclipse funzioni allo stesso modo ma bisognerebbe sentire qualcuno che lo usa.

franksisca
21-07-2009, 21:07
Le librerie dinamiche devono essere estratte perchè il contenuto del jar non è parte dei percorsi di ricerca delle librerie dinamiche. Puoi distribuirle col jar ed estrarle dinamicamente oppure puoi semplicemente distribuire la tua applicazione come archivio zip. A conti fatti è la stessa cosa solo che lasci l'estrazione all'utente. Lo stesso vale per le immagini anche se normalmente queste sono incluse nel jar insieme a tutte le risorse "statiche".quindi continuo a metterle nella stessa root del jar e poi tramite setupfree li faccio installare (come ho fatto finora).

volevo solo sapere se la mia procedura era giusta :D


Per quanto riguarda il come bisogna vedere l'ide. Ad esempio in Netbeans ci sono dei percorsi che il cui contenuto è automaticamente incluso nel jar (tipicamente ciò che è contenuto in src che non sia un file .java). Credo che Eclipse funzioni allo stesso modo ma bisognerebbe sentire qualcuno che lo usa.

quindi se io voglio mettere una immagine e metterla nel jar come faccio???

io per ora sto mettendo, di solito, in una cartella a livello più basso del jar e poi tramite il setup la posiziono nell'istallazione allo stesso livello.
se ho capito bene, invece, basta metterla nella cartella src e caricarla normalmente (con il getresource) e poi quando creo il jar dovrebbe automaticamente riconoscerla, giusto???

al momento sto usando la prima opzione perchè è lo sfondo di un pannello, quindi per poterla "eventualmente" modificare al volo.

PGI-Bis
21-07-2009, 21:56
Se puoi non usare eseguibili che quando vedi un'applicazione Java con un exe ti viene già il magone in partenza.

Crea le risorse che sono necessarie al programma alla prima esecuzione estraendole dal jar stesso. Per esecuzioni successive procedi ad una nuova estrazione solo se i file già estratti risultino in qualche modo corrotti - cosa che non dovrebbe capitare ma è meglio pensarci prima che dopo.

Tieni presente che non hai bisogno di gestire "manualmente" la decompressione del contenuto di un jar: getClass().getResourceAsStream ti da già un flusso zip che puoi leggere e riversare all'esterno con tre righe in croce.

Se il tuo programma usa un'immagine di sfondo e offre all'utente la possibilità di cambiare quell'immagine avrai l'immagine predefinta all'interno del jar ed una funzione di configurazione che permetterà all'utente di cambiare immagine. A quel punto in avvio determinerai attraverso i parametri di configurazione del programma quale immagine caricare. Se per avventura l'immagine scelta dall'utente dovesse sparire potrai sempre tornare all'immagine predefinita. E questo non richiede lo spargimento di file.

L'ideale per me è sempre stato: un file, un click. Niente procedure guidate per l'installazione, niente spargimento di file, il file che ti arriva è il programma pronto all'esecuzione. Se c'è qualcosa da configurare lo si configura nel programma.

Tieni conto tuttavia che "l'installer fa fico" e quanti più file riesci a spargere in giro per il disco dell'utente tanto più sei profescional.

RaouL_BennetH
21-07-2009, 22:10
L'ideale per me è sempre stato: un file, un click. Niente procedure guidate per l'installazione, niente spargimento di file, il file che ti arriva è il programma pronto all'esecuzione. Se c'è qualcosa da configurare lo si configura nel programma.



Anche io preferisco per le piccole applicazioncine che faccio in azienda fare così (copio semplicemente l'eseguibile sul/sui pc).

Premetto che il mio non è un discorso professionale ;)

Però, mio malgrado ho preferito poi in seguito ampliare un pò e, seppur mantenendo l'idea di non installare nulla, copio semplicemente una directory che oltre a contenere il file eseguibile, mi contiene anche qualche semplice file di testo di configurazioni varie, in modo che, se per esempio mi dovesse cambiare una connessione ad un database, non sarei costretto a ricompilare per ottenere un nuovo eseguibile da sostituire ma cambiare direttamente il valore nel file di testo.

franksisca
21-07-2009, 22:11
Tieni conto tuttavia che "l'installer fa fico" e quanti più file riesci a spargere in giro per il disco dell'utente tanto più sei profescional.

:D :D

il fatto di non aver mai fatto applicazioni da distribuire mi sta aprendo molti punti oscuri.

infatti pensavo che l'insaller oltre che figo fosse utile...infatti sto utilizzanto un cretore di .rpm er linux X_X


quindi tu mi consigli di mettere librerie, dll, jpg, cazzi&mazzi vari tutti nel jar....
poi siccome vista (7) scassa i maron glasse per la creazione dei file come faccio?

perchè se l'utente non è admin non mi permette di creare i file. per questo ho usao la dll ...

PGI-Bis
21-07-2009, 23:46
Se l'utente ha copiato il file del programma in una cartella X deve avere almeno il permesso "write" per quella cartella altrimenti non avrebbe potuto creare il file del programma in quel punto.

franksisca
21-07-2009, 23:51
Se l'utente ha copiato il file del programma in una cartella X deve avere almeno il permesso "write" per quella cartella altrimenti non avrebbe potuto creare il file del programma in quel punto.

e anche tu hai ragione :D

fero86
22-07-2009, 01:32
Percui quando fai un'affermazione di questo tipo:

[...]

per me è poco circostanziata, ovvero i motivi per cui Java sucks (così come tutti gli altri linguaggi, ognuno con i suoi sucks, chi più chi meno) sono altri, non di certo questo (che ripeto, non ha niente a che vedere con il linguaggio in se). non ha niente a che vedere col linguaggio ma ha a che vedere con le API in dotazione, quindi comunque con la piattaforma Java.
é un sucks eccome, visto che tutte le sante volte che io devo scrivere un'applicazione desktop in Java (e non é che non mi sia capitato eh...) mi trovo di fronte sempre a questo stesso problema e la soluzione piu ragionevole alla fine risulta sempre essere quella di insozzare il proprio ramo di directories creando cosi un'applicazione per nulla "Vista-friendly".



fero86, se l'idea di dover fare una libreria dinamica per windows ti spaventa così tanto vedrai che leggendo qua:

http://java.sun.com/docs/books/jni/html/jniTOC.html

e facendo riferimento a questo:

http://msdn.microsoft.com/en-us/library/aa139672.aspx

anche tu sarai in grado di farlo. grazie per aver scritto il post piu inutile della storia.
ad ogni modo, che io sia in grado di farlo non vuol dire che sia una scelta ragionevole.


[...] Personalmente aderisco alla prima ritenendo che distribuire un programma a terzi sia come essere invitati in casa d'altri: se ti fanno accomodare in salotto non significa che sei autorizzato a ficcare il naso nel ripostiglio. molto divertente, ma non sono delle simpatiche metafore i motivi per cui determinate guidelines indicano che le applicazioni utente debbano scrivere in determinate cartelle. un'applicazione eseguita nel contesto di sicurezza dell'utente non dovrebbe mai scrivere nelle proprie cartelle di installazione perché l'utente non deve avere i permessi per scrivere da quelle parti (e intendo ne' per scrivere files esistenti ne' per creare nuovi files), altrimenti aumenta il rischio che lo faccia un virus visto che i virus nella quasi totalitá dei casi vengono eseguiti nel contesto di sicurezza dell'utente.

malocchio
22-07-2009, 08:20
Se l'utente ha copiato il file del programma in una cartella X deve avere almeno il permesso "write" per quella cartella altrimenti non avrebbe potuto creare il file del programma in quel punto.

molto divertente, ma non sono delle simpatiche metafore i motivi per cui determinate guidelines indicano che le applicazioni utente debbano scrivere in determinate cartelle. un'applicazione eseguita nel contesto di sicurezza dell'utente non dovrebbe mai scrivere nelle proprie cartelle di installazione perché l'utente non deve avere i permessi per scrivere da quelle parti (e intendo ne' per scrivere files esistenti ne' per creare nuovi files), altrimenti aumenta il rischio che lo faccia un virus visto che i virus nella quasi totalitá dei casi vengono eseguiti nel contesto di sicurezza dell'utente.

Concordo con fero: ammettiamo che un amministratore "installi" un programma system-wide, magari senza aver usato un installer ma scompattandolo manualmente, quindi in una cartella di sistema, in modo che tutti possano avviarla. Ovviamente gli utenti normali non hanno permessi di scrittura in tali cartelle, o non dovrebbero averli. Quindi sembra più plausibile avere tutto già pronto per l'esecuzione e scrivere su disco solamente le preferenze dell'utente, appunto nella home dell'utente.
Vedi che ci sono due strade:
- creo un'app portabile che scrive solo nella sua directory, perdendo la possibilità di avere un'unica copia nel sistema multi-utente.
- creo un'app (non è strettamente necessario un installer) che si avvia dalle cartelle di sistema e va a scrivere singolarmente per ogni utente le informazioni personali nella home

Quindi applicazione portabile non è sinonimo di applicazione stand-alone, a questo punto.

banryu79
22-07-2009, 08:46
non ha niente a che vedere col linguaggio ma ha a che vedere con le API in dotazione, quindi comunque con la piattaforma Java.
é un sucks eccome, visto che tutte le sante volte che io devo scrivere un'applicazione desktop in Java (e non é che non mi sia capitato eh...) mi trovo di fronte sempre a questo stesso problema e la soluzione piu ragionevole alla fine risulta sempre essere quella di insozzare il proprio ramo di directories creando cosi un'applicazione per nulla "Vista-friendly".

Beh fero, che il discorso non avesse a che vedere con il linguaggio ma con la piattaforma mi sembrava cristallino, l'avevo anche specificato:

C'è anche da dire però, a voler mettere i puntini sulle "i", che è comunque fattibile, e non dipende dal linguaggio, quanto dalla piattaforma, che a differenza del citato C# che si appoggia a librerie create dagli stessi autori del sistema operativo su cui può girare, con tutti i fichissimi binding alle WinAPI (e vorrei anche vedere), Java non nasce di suo per lavorare specificatamente con Windows (anche se sicuramente i binding a metodi messi a disposizine nel JDK standard che ti permettano di accedere a variabili di ambiente well known come %APPDATA% in Windows possono benissimo essere implementati).
...


Quindi alla fine il tuo discorso, se non ho capito male, è che la piattaforma Java "sucks" perchè non ha una API specifica per il recuperare il percorso memorizzato nella variabile di ambiente %APPDATA% dei sistemi Windows?

fero86
22-07-2009, 11:10
Beh fero, che il discorso non avesse a che vedere con il linguaggio ma con la piattaforma mi sembrava cristallino, l'avevo anche specificato:


Quindi alla fine il tuo discorso, se non ho capito male, è che la piattaforma Java "sucks" perchè non ha una API specifica per il recuperare il percorso memorizzato nella variabile di ambiente %APPDATA% dei sistemi Windows? fosse solo quello... la piattaforma Java "sucks" anche per altri motivi, di cui questo é legato alle API mentre molti altri sono legati al linguaggio :D

franksisca
22-07-2009, 11:12
fosse solo quello... la piattaforma Java "sucks" anche per altri motivi, di cui questo é legato alle API mentre molti altri sono legati al linguaggio :D

scusa puoi elencare i motivi???


sinceramente aavendo studiato un bel pò di teoria non mi sembra catastrofica come la fai tu...

malocchio
22-07-2009, 11:17
scusa puoi elencare i motivi???


sinceramente aavendo studiato un bel pò di teoria non mi sembra catastrofica come la fai tu...

fosse solo quello... la piattaforma Java "sucks" anche per altri motivi, di cui questo é legato alle API mentre molti altri sono legati al linguaggio :D

Sarà il solito YourLanguageSucks (link (http://wiki.theory.org/YourLanguageSucks#Java_sucks_because:))

Ora passiamo al resto... quali sarebbero i "sucks" della piattaforma? Tralasciando le performance, che sono una partita persa.

fero86
22-07-2009, 12:24
vi risponderó con la tecnica di Hokuto del quote incrociato (franksisca-malocchio, franksisca-malocchio).


scusa puoi elencare i motivi???
Sarà il solito YourLanguageSucks (link (http://wiki.theory.org/YourLanguageSucks#Java_sucks_because:)) :cool:


sinceramente aavendo studiato un bel pò di teoria non mi sembra catastrofica come la fai tu... non lo é assolutamente, Java é una piattaforma di ottima qualitá infatti; con i suoi sucks ma di ottima qualitá.


Ora passiamo al resto... quali sarebbero i "sucks" della piattaforma? Tralasciando le performance, che sono una partita persa. vieni a sfidare me ad argomentare una tesi che tu mi hai messo in bocca quando poi tu ne sventoli un'altra ancora piu clamorosa? dove ho scritto che la piattaforma Java é piena di sucks che non riguardano il linguaggio?
sentiamo invece le tue argomentazioni: scrivi un benchmark, piglia un profiler e vediamo questi risultati catastrofici, e mi raccomando che sia tutto molto riproducibile.

Frank1962
22-07-2009, 12:27
ognuno ha i suoi modi di porsi, ergo, leggendo gli ultimi reply di questo thread, chiedo a PGI di non considerare più la continuazione di questa discussione a meno di non voler passare da Bis a Tris facendo perdere per un bel pò di tempo al forum un ottimo poster.....

fero86
22-07-2009, 12:31
ognuno ha i suoi modi di porsi, ergo, leggendo gli ultimi reply di questo thread, chiedo a PGI di non considerare più la continuazione di questa discussione a meno di non voler passare da Bis a Tris facendo perdere per un bel pò di tempo al forum un ottimo poster..... fake di PGI? :asd:

banryu79
22-07-2009, 12:41
ognuno ha i suoi modi di porsi, ergo, leggendo gli ultimi reply di questo thread, chiedo a PGI di non considerare più la continuazione di questa discussione a meno di non voler passare da Bis a Tris facendo perdere per un bel pò di tempo al forum un ottimo poster.....
Solo una curiosità: perchè richiami l'utente PGI-bis?
(Sembra un richiamo, il post che hai scritto, quasi fosse un atto di moderazione).

Non mi pare che PGI abbia ne offeso ne alzato i toni della discussione...
E poi non mi pare neanche tanto bello moderare da utente un altro utente, quando i presupposti per farlo in modo sensato mancano...

Tutto questo senza volerti mancare di rispetto, ne incitare a un flame: è solo un desiderio di chiarezza da parte mia, perchè ho l'impressione di non capire bene la situazione che si è venuta a creare.

PGI-Bis
22-07-2009, 13:18
Non intendevo urtare la tua sensibiltà fero86 ma non vedo la ragione per cui tu debba insozzare la cartella dell'eseguibile Java se lo ritieni sbagliato. Quando dico che le librerie dinamiche devono essere poste nella cartella dell'eseguibile lo dico nel contesto di un'applicazione "portable". Non è l'unica opzione: si possono mettere in uno qualsiasi dei percorsi predefiniti per le librerie native della piattaforma java.

Se quando hai scritto le tue applicazioni desktop Java hai ravvisato la necessità insozzante è perchè non conoscevi l'alternativa. Non è che sia un delitto ma non è colpa della piattaforma.

Un programma portable non può scrivere in altre cartelle. E' creato nell'ottica di dover esistere su un drive rimuovibile: la configurazione ed i dati si muovono con il programma. Da ciò deriva la necessità di dover scrivere nella propria cartella.

Deriva anche la non condivisibilità dell'eseguibile: se due utenti avviano lo stesso programma i dati delle due sessioni andranno a confondersi nelle stesse cartelle, la rimozione del programma da parte di un utente si porta via anche i dati degli altri eccetera. Ci sono un tot di problemi logici oltre alla questione fisica dei permessi di accesso ai file.

L'installazione multiutente di un programma portabile deve necessariamente essere una replicazione dello stesso file su più percorsi altrimenti o il programma non è portabile o non ha bisogno di scrivere in locale o non funziona. Tertium non datur.

Comunque non è un obbligo quello di fare un'applicazione portabile: è una scelta.

Alternative almeno due. La prima è Java Web Start, specialmente per una intranet. La seconda è l'application server. Un Application Server J2EE a là Glassfish è prima di tutto un distributore di applicazione Java e incidentalmente di applicazioni web. Entrambe relegano alla preistoria aggiornamenti, patch, distribuzione, versioni diverse per os diversi eccetera eccetera.

Anche Squeak ha un sistema analogo (Monticello). L'installer è un po' masochistico.

PGI-Bis
22-07-2009, 14:19
un'applicazione eseguita nel contesto di sicurezza dell'utente non dovrebbe mai scrivere nelle proprie cartelle di installazione perché l'utente non deve avere i permessi per scrivere da quelle parti (e intendo ne' per scrivere files esistenti ne' per creare nuovi files), altrimenti aumenta il rischio che lo faccia un virus visto che i virus nella quasi totalitá dei casi vengono eseguiti nel contesto di sicurezza dell'utente.

La questione è molto interessate.

E' un problema se un virus può scrivere nella cartella di un eseguibile in un sistema in cui ogni utente ha delle limitazioni di permesso?

Diciamo che c'è un eseguibile jar non certificato: il virus lo sovrascrive e l'utente lo avvia credendo che sia l'originale.

A questo punto il virus che fa? Direi nulla più di quanto potesse fare il programma originale. Cioè è comunque limitato dalle credenziali dell'utente. O sbaglio? Potrà mettere un programma in esecuzione automatica per qualsiasi utenza? No se non può farlo l'utente.

Forse è la condivisione delle applicazioni tra utenti con permessi diversi ad essere pericolosa più che la possibilità di scrivere nella cartella del programma.

E poi cambia qualcosa se chiudo la porta alla sovrascrittura dell'eseguibile e la lascio aperta ai plug-in che metto in application-data?

malocchio
22-07-2009, 15:03
Forse è la condivisione delle applicazioni tra utenti con permessi diversi ad essere pericolosa più che la possibilità di scrivere nella cartella del programma.Potresti spiegare il perché?

E poi cambia qualcosa se chiudo la porta alla sovrascrittura dell'eseguibile e la lascio aperta ai plug-in che metto in application-data?Beh una sovrascrittura dell'eseguibile coinvolgerebbe tutti gli utenti che lo usano, mentre una del plugin coinvolgerebbe solo l'utente che ha installato quel plugin nella cartella personale. O no?


vieni a sfidare me ad argomentare una tesi che tu mi hai messo in bocca quando poi tu ne sventoli un'altra ancora piu clamorosa? dove ho scritto che la piattaforma Java é piena di sucks che non riguardano il linguaggio?
sentiamo invece le tue argomentazioni: scrivi un benchmark, piglia un profiler e vediamo questi risultati catastrofici, e mi raccomando che sia tutto molto riproducibile.C'è stata un'incomprensione, allora. Pensavo che tu considerassi negativamente la piattaforma.

Perché mi inviti ad argomentare? E' storia che applicazioni scritte in Java siano più lente rispetto a molte altre...

ps. evita di dire che io ti ho sfidato per favore, stiamo chiacchierando :rolleyes:

PGI-Bis
22-07-2009, 15:32
Potresti spiegare il perché?

Il perchè è nel rilievo che hai fatto sulla sovrascrittura.

Cioè se l'eseguibile è condiviso allora non devo poterlo cambiare, altrimenti consentiamo una migrazione dei permessi (il virus cambia l'eseguibile per un utente limitato che inietta del codice in una cartella di sistema quando è lanciato da un utente con i permessi di amministrazione del sistema).

Ma se tratto i programmi come fossero documenti e lascio che ognuno abbia la sua copia questo problema non c'è.

Forse le utenze non dorebbero essere gerarchiche ma mutualmente esclusive: l'amministratore non può pucciare il naso nei programmi dell'utente x perchè x potrebbe aver installato un malware che eseguito con permessi più ampi sarebbe in grado di provocare dei danni. Se vuole andare a sistemare qualcosa per l'utenza X allora deve usare le credenziali di X o un'emulazione delle credenziali di X.

fero86
23-07-2009, 22:58
Non intendevo urtare la tua sensibiltà fero86 ma non vedo la ragione per cui tu debba insozzare la cartella dell'eseguibile Java se lo ritieni sbagliato. é vero che é possibile ottenere il percorso della cartella corretta in cui mettere i dati prodotti dal programma, ma quel modo mi fa perdere la portabilitá. sul resto del tuo post sostanzialmente taglio perché hai scritto fiumi di parole basate su un concetto di portabilitá diverso da quello che io in genere leggo e intendo e non capisco cosa c'entra con quello che si stava dicendo: per me un'applicazione portabile é un'applicazione che gira cosi com'é (o con pochissima fatica da parte dello sviluppatore) su molte piattaforme differenti, come Windows, Linux e Mac. la tecnologia Java SE aiuta tantissimo in questo perché un jar che non si appoggia a librerie native puó girare senza modificare nulla ovunque sia installato il JRE appropriato. da quanto ho capito tu invece parli di applicazioni auto-contenute in un'unica cartella che hanno il vantaggio di poter essere portate su flash drive ed eseguite ovunque perché non richiedono un'installazione con permessi particolari (come eclipse insomma).


Se quando hai scritto le tue applicazioni desktop Java hai ravvisato la necessità insozzante è perchè non conoscevi l'alternativa. Non è che sia un delitto ma non è colpa della piattaforma. la conoscevo eccome invece: non capisco perché tu debba dare per scontate cose che non ti sono state dette, io in passato ho avuto anche occasione di scrivere librerie native interfacciate a Java tramite JNI (una sola per la veritá, e adesso in tutta sinceritá non ricordo molto ma un'idea della complessitá mi é rimasta).


E' un problema se un virus può scrivere nella cartella di un eseguibile in un sistema in cui ogni utente ha delle limitazioni di permesso? dipende da che cosa ha intenzione di fare il programma con quel file; solitamente é un problema, il virus ce l'avrá anche avuto un intento nello scrivere li. un esempio molto fesso che mi viene in mente: la cartella di installazione (non scrivibile, solo leggibile/eseguibile, perdonate l'enorme approssimazione) del programma potrebbe contenere un file di licenza d'uso e se un virus lo cancellasse solamente una copia di backup della licenza potrebbe salvare i quattrini spesi dall'utente per acquistare quel software.
prima che arrivi l'obiezione: i file di licenza solitamente sono per-machine, non per-user, quindi l'esempio pur fesso calza piuttosto bene.


Diciamo che c'è un eseguibile jar non certificato: il virus lo sovrascrive e l'utente lo avvia credendo che sia l'originale.

A questo punto il virus che fa? Direi nulla più di quanto potesse fare il programma originale. che equivale a potenziali disastri di proporzioni inimmaginabili: l'utente naturalmente ha i permessi di cancellare i suoi documenti, ti dice niente? in questo contesto potresti far perdere ad un poveraccio ore di lavoro. o forse giorni? settimane? mesi? i tempi sono dell'ordine di grandezza che vuoi tu :D
non credere che i virus writers di questi tempi non abbiano piu voglia di fare cose simili: abbastanza di recente mi sono alquanto divertito nel leggere di virus "usurai" che minacciavano di cancellare questo mondo e quell'altro se l'utente non avesse depositato consistenti somme di denaro su qualche conto svizzero :D


Forse è la condivisione delle applicazioni tra utenti con permessi diversi ad essere pericolosa più che la possibilità di scrivere nella cartella del programma. questo naturalmente si se tu ragioni nell'ottica della difesa del sistema, ma i dati dell'utente sono molto piu importanti di file di sistema: all'utente frega poco di dover formattare o meno se i dati sono salvi sulla copia di backup.


E poi cambia qualcosa se chiudo la porta alla sovrascrittura dell'eseguibile e la lascio aperta ai plug-in che metto in application-data? chi l'ha detto che i plug-in si mettono li? i plug-in sono programmi come tutti gli altri e vanno installati come tutti gli altri.


Perché mi inviti ad argomentare? E' storia che applicazioni scritte in Java siano più lente rispetto a molte altre... ecco appunto, argomenta argomenta...

malocchio
24-07-2009, 09:00
ecco appunto, argomenta argomenta...Un'applicazione Java è oggettivamente più dispendiosa da avviare. Ovviamente molti miglioramenti sono stati fatti, e in alcuni aspetti particolari può arrivare ad essere addirittura più veloce del C++. E' comunque molto difficile confrontare Java/nativo.

Ammetto di essere vittima di un "mito"

LINK (http://www.idiom.com/~zilla/Computer/javaCbenchmark.html)

banryu79
24-07-2009, 09:40
Un'applicazione Java è oggettivamente più dispendiosa da avviare.
A questo proposito, un articolo (http://blogs.oreilly.com/digitalmedia/2005/02/how-to-make-a-desktop-applicat.html) che illustra una strategia interessante che ho letto stamani... (ed è old, visto che è del 2005)

PGI-Bis
24-07-2009, 13:39
Non che wikipedia sia l'alma summa delle conoscenza ma è un buon inizio.

http://en.wikipedia.org/wiki/Portable_application

La portabilità nell'altro senso - in effetti il termine calza bene per entrambi i contesti - non la perdi per il fatto di usare una libreria dinamica. Ci sono montagne di API java che dietro le quinte fanno uso di librerie dinamiche pur essendo perfettamente multi-piattaforma.

Capita perchè la libreria dinamica dipende dalla piattaforma ma il meccanismo di risoluzione del percorso di quella libreria no.

Qui il problema è semmai se esista o non esista un omologo di APPDATA in OSX-Solaris-Linux-BSD.

banryu79
24-07-2009, 13:47
Qui il problema è semmai se esista o non esista un omologo di APPDATA in OSX-Solaris-Linux-BSD.
Esattamente.
Il discorso che facevo a fero86, qualche manciata di post fa, è che lo scopo e l'esistenza di %APPDATA% è una precisa politica dei sistemi Windows.

Java non è nato per operare specificatamente su Windows, al contrario ad esempio della piattaforma .NET (tanto per avere un termine di paragone), la quale ha a disposizione, per così dire, "una base assiomatica" molto più ampia sulla quale operare...

Considerato questo, la deficienza di una apposita API nel JDK standard per il recupero di tale path non fa gridare allo scandalo...

^TiGeRShArK^
24-07-2009, 17:11
Per uno che sa usare Java trovare la cartella APPDATA è difficile quanto tagliarsi le unghie.
direi quanto bere un bicchiere d'acqua....
tagliarsi le unghie è + lungo.

^TiGeRShArK^
24-07-2009, 17:17
Premetto che non conosco nulla delle API di windows e il fatto che io sia riuscito ad ottenere il percorso di APPDIR in 5 minuti netti da una misura della difficoltà del problema.

Uno va a guardare come si fa ad ottenere la cartella APPDIR nelle API di Windows e, stando a google, risultano quattro linee di codice C/C++:

ITEMIDLIST* list;
char appdir[500];
SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &list);
SHGetPathFromIDList(list, appdir);

A questo punto appdir contiene la cartella APPDATA.

Ora, Java ha questo straordinario e apparentemente ignoto pezzo di sè chiamato JNI. Diciamo che vogliamo copiare appdir in uno StringBuilder. Giusto per vedere. Bene, supponendo che questo StringBuilder sia creato in Java ci troviamo con;

jobject stringBuilder; //lo StringBuilder: tutti i reference JNI sono jobject salvo un paio

Diciamo che vogliamo riempire lo stringBuilder un carattere alla volta. StringBuilder ha il metodo append(char). Usiamo questo. Prima prendiamo il metodo:

jclass stringBuilderClass = env->FindClass("java/lang/StringBuilder");
jmethodID appendChar = env->GetMethodID(stringBuilderClass, "append", "(C)Ljava/lang/StringBuilder;");

poi lo invochiamo. Vogliamo dire "per ogni carattere in appdir finchè ce ne sono stringBuilder.append(c)?". Scriviamo:

for(int i = 0; (i < 500) & (appdir[i] != '\0'); i++) {
env->CallVoidMethod(stringBuilder, appendChar, appdir[i]);
}

"env" è un puntatore JNIEnv che ottieni automaticamente da JNI quando realizzi un metodo nativo.

Questo tanto per dare un'idea dell'invocazione di metodi e di come appaiono gli oggetti JNI.

Passiamo al nostro problema.

Voglio ottenere la cartella "APPDATA".

1. Creo una classe Java con un metodo nativo (i nomi sono arbitrari):

package it.tukano.winapi;

public class WinApi {

public native String getAppDir();
}

Compilo:

javac -d . *.java

Poi creo l'header JNI:

javah it.tukano.winapi.WinApi

L'header contiene il prototipo della funzione JNI che rappresenta la controparte nativa di getAppDir, cioè la funzione che sarà invocata ogni volta che io dirò:

winApi.getAppDir();

Il prototipo è un po' strano a vedersi ma è al 99% convenzionale. L'unica cosa da notare è che il metodo nativo getAppDir() è senza argomenti e restituisce uno String, la controparte nativa restituisce un jstring e ha due argomenti. JNIEnv è il puntatore alle funzioni globali di JNI, jobject è un riferimento al "this" dell'invocazione Java.

Comunque la definizione di quella funzione è brevissima:

//file dllmain.cpp
#include "it_tukano_winapi_WinApi.h"
#include <shlobj.h>

JNIEXPORT jstring JNICALL Java_it_tukano_winapi_WinApi_getAppDir
(JNIEnv *env, jobject obj)
{
int SIZE = 500;
char buffer[SIZE];
ITEMIDLIST* list;
SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &list);
SHGetPathFromIDList(list, buffer);
return env->NewStringUTF(buffer);
}



NewStringUTF è una funzione JNI che dato un buffer di char restituisce una nuova stringa java (che in JNI è un jstring).

Compilando con il tuo ide c++ottieni la tua dll. Per usare il tuo WinApi dirai:

public class Main {

public static void main(String[] args) {
System.loadLibrary("winapi");
it.tukano.winapi.WinApi winApi = new it.tukano.winapi.WinApi();
System.out.println(winApi.getAppDir());
}
}

Sono 28 linee di codice, prova inclusa.
:mbe:
..bastava fare così mi sa:

Map<String, String> env = System.getenv();
System.out.println(env.get("APPDATA"));

^TiGeRShArK^
24-07-2009, 17:19
c'é sempre il dubbio che un'intera DLL sia overkilling per chiamare una sola API; la possibilitá che esiste in C# di invocare direttamente l'API ad esempio toglierebbe l'imbarazzo.

tra l'altro un programmatore che sappia usare Java raramente sa usare anche il C++ e men che mai le API Win32, di conseguenza il problema non é cosi semplice come tagliarsi le unghie, specialmente se per risolverlo ricorre a chissá quali minchiate trovate su Google; il tuo codice ad esempio é semi-delirante, avresti dovuto scrivere una cosa del genere:

CHAR szBuffer[MAX_PATH];
HRESULT hr = SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szBuffer);
if (FAILED(hr) || (hr == S_FALSE))
{
// gestire l'errore
}


no è semplice come bere un bicchiere d'acqua...
due righe di codice, ma volendo anche una facendo così:

System.out.println(System.getenv().get("APPDATA"));


..cmq è incredibile vedere quante pippe mentali vi siete fatti per leggere il valore di una variabile d'ambiente.. :fagiano:

PGI-Bis
24-07-2009, 17:28
Ma sai che non avevo mai visto getenv?

Ma pensa cosa non si scopre dalla sera alla mattina :D

In pratica 4 pagine per niente.

PGI-Bis
24-07-2009, 17:32
Che però non va bene perchè non accede alla proprietà di sistema. Serve JNI.

^TiGeRShArK^
24-07-2009, 17:33
Ma sai che non avevo mai visto getenv?

Ma pensa cosa non si scopre dalla sera alla mattina :D

In pratica 4 pagine per niente.

e infatti era pure quello che pensavo io. :D

cmq più che altro il problema con windows vista è quando si scrivono dei servizi di rete in cui non si ha accesso alla cartella dei dati applicazioni dell'utente....
E per quello quando ho un pò di tempo devo trovare un workaround per fare funzionare un mio software su vista dato che per scambiarsi i dati con l'interfaccia di controllo utilizzavo la cartella file comuni. :fagiano:

banryu79
24-07-2009, 17:33
Che però non va bene perchè non accede alla proprietà di sistema. Serve JNI.
[PIGRIZIA MODE ON]
Ehm, e a che serve, te che l'hai provata? :D

^TiGeRShArK^
24-07-2009, 17:34
Che però non va bene perchè non accede alla proprietà di sistema. Serve JNI.

in che senso non accede alle proprietà di sistema? :mbe:

^TiGeRShArK^
24-07-2009, 17:34
[PIGRIZIA MODE ON]
Ehm, e a che serve, te che l'hai provata? :D

io l'ho provata ora su xp e funziona restituendo il path di %APPDATA%

PGI-Bis
24-07-2009, 17:40
Sembra che restituisca non la proprietà del sistema ma una copia per processo della proprietà di sistema.

In pratica se fai:

set APPDATA="c:\ti frego io ti frego"

e poi lanci il programma con l'accesso "JNI" ottieni comunque la cartella APPDATA mentre attraverso getenv ti arriva c:\ti frego io ti frego.

In pratica JNI e getenv fanno la stessa cosa "a meno che...". Non so quanto sia desiderabile quel "a meno che".

banryu79
24-07-2009, 17:41
[PIGRIZIA MODE OFF]
Bon, mi sono stampato tutta la mappa, sotto WinXP, e posso dire che ottengo un pasto di roba utile a fare deploy delle applicazioni a la Windows.
Anche a me funge :fagiano:

banryu79
24-07-2009, 17:43
In pratica se fai:

set APPDATA="c:\ti frego io ti frego"

e poi lanci il programma con l'accesso "JNI" ottieni comunque la cartella APPDATA mentre attraverso getenv ti arriva c:\ti frego io ti frego.

Scusa PGI, mi spiegheresti la differenza concettuale?
Perchè non ho capito...

^TiGeRShArK^
24-07-2009, 17:44
Sembra che restituisca non la proprietà del sistema ma una copia per processo della proprietà di sistema.

In pratica se fai:

set APPDATA="c:\ti frego io ti frego"

e poi lanci il programma con l'accesso "JNI" ottieni comunque la cartella APPDATA mentre attraverso getenv ti arriva c:\ti frego io ti frego.

In pratica JNI e getenv fanno la stessa cosa "a meno che...". Non so quanto sia desiderabile quel "a meno che".

vabbè..pure se un programma modifica in precedenza il registro di sistema c'è lo stesso problema mi sa :p
Quindi a 'sto punto io preferisco risolvere il problema con una riga di codice se tanto c'è sempre il rischio che qualcuno può far si che il risultato sia errato. :p

^TiGeRShArK^
24-07-2009, 17:45
Scusa PGI, mi spiegheresti la differenza concettuale?
Perchè non ho capito...

La variabile d'ambiente risiede in memoria invece le property di sistema sono quelle scritte sul registro, sempre se ho capito cosa intende.
Ma comunque non si ha la certezza nemmeno con JNI di puntare alla cartella corretta se un programma modifica il path di APPDATA all'interno del registro....

PGI-Bis
24-07-2009, 17:51
Non è neanche detto che sia una cosa malvagia che il valore sia relativo. Si può sempre usare per dei test.

Sai, "l'importante è saperlo", poi uno decide. Io userei getenv.

^TiGeRShArK^
24-07-2009, 17:54
Non è neanche detto che sia una cosa malvagia che il valore sia relativo. Si può sempre usare per dei test.

Sai, "l'importante è saperlo", poi uno decide. Io userei getenv.

io pure. :D

banryu79
24-07-2009, 17:58
Io pure, sottoscrivo :cry:

Allora possiamo riunirci in capitolo e costringere fero86 ad "abiurare" quella che è una ingusta attribuzione di uno "sucks" alla piattaforma Java?
Vado a prendere le tenaglie arroventate... :asd:

(oh, si scherza eh, è venerdì sera :gluglu: )

^TiGeRShArK^
24-07-2009, 18:57
Io pure, sottoscrivo :cry:

Allora possiamo riunirci in capitolo e costringere fero86 ad "abiurare" quella che è una ingusta attribuzione di uno "sucks" alla piattaforma Java?
Vado a prendere le tenaglie arroventate... :asd:

(oh, si scherza eh, è venerdì sera :gluglu: )

oh yes :cool:

:asd:

franksisca
25-07-2009, 11:50
quindi fatemi capire.

tutta la prcedutra con la jni può essere saltata usando quella chiamata???

PGI-Bis
25-07-2009, 11:56
Esatto. Io ti consiglio di usare comunque JNI per via della possibilità di sovrascrivere il valore di getenv.

(ma personalmente userei getenv perchè normalmente predico bene e razzolo malissimo :D).

^TiGeRShArK^
25-07-2009, 12:23
quindi fatemi capire.

tutta la prcedutra con la jni può essere saltata usando quella chiamata???

yes, se ti serve semplicemente il valore di APPDATA puoi usare la mia riga di codice. :p

malocchio
26-07-2009, 14:11
System.out.println(System.getenv().get("APPDATA"));


..cmq è incredibile vedere quante pippe mentali vi siete fatti per leggere il valore di una variabile d'ambiente.. :fagiano:

:rotfl: Ma quanto siamo co***oni :rotfl: