Questa è la configurazione:
- OSX Yosemite
- Servizio basato su Java avviato utilizzando un LaunchDaemon
- Il servizio viene avviato con un utente personalizzato che viene creato durante l'installazione
- L'utente ha una home directory personalizzata per salvare determinate informazioni, come le preferenze
Ecco come viene creato l'utente:
DEAMON_USER="{{daemonUser}}"
HOME_DIRECTORY="{{homeDirectory}}"
SERVICE_DESCRIPTION="{{displayName}}"
# find the next UID and GID that is below 500, so that we can create the service user
# if the user or group already exists, it will use this existing ID and still do the rest. We might have changes to commit.
NEXTUID=$(ID='dscl . -read "/Users/${DEAMON_USER}" UniqueID 2> /dev/null | awk '{print $2}'' && [ ! -z "$ID" ] && echo "$ID" || dscl . -list /Users UniqueID | awk 'BEGIN{i=0}{if($2>i&&$2<500)i=$2}END{print i+1}')
NEXTGID=$(ID='dscl . -read "/Groups/${DEAMON_USER}" PrimaryGroupID 2> /dev/null | awk '{print $2}'' && [ ! -z "$ID" ] && echo "$ID" || dscl . -list /Groups PrimaryGroupID | awk 'BEGIN{i=0}{if($2>i&&$2<500)i=$2}END{print i+1}')
echo "Will use '${NEXTUID}' as UserID and '${NEXTGID}' as group ID for User '${DEAMON_USER}'"
#########################################################################################################
dscl . -create "/Users/${DEAMON_USER}" UniqueID "${NEXTUID}"
dscl . -create "/Users/${DEAMON_USER}" PrimaryGroupID "${NEXTGID}"
dscl . -create "/Users/${DEAMON_USER}" NFSHomeDirectory "${HOME_DIRECTORY}"
# Can't login as standard user
dscl . -create "/Users/${DEAMON_USER}" UserShell /usr/bin/false
dscl . -create "/Users/${DEAMON_USER}" RealName "${SERVICE_DESCRIPTION} Administrator"
# Unusable password for standard users
dscl . -create "/Users/${DEAMON_USER}" Password \*
#########################################################################################################
#########################################################################################################
dscl . -create "/Groups/${DEAMON_USER}" PrimaryGroupID "${NEXTGID}"
# Unusable password for standard users
dscl . -create "/Groups/${DEAMON_USER}" Password \*
#########################################################################################################
# make home directory
mkdir -p "${HOME_DIRECTORY}/Library/Preferences" && chown -R "${DEAMON_USER}:${DEAMON_USER}" "${HOME_DIRECTORY}" || true
Generalmente il servizio crea preferenze utente che vengono quindi memorizzate nella directory ~/Library/Preferences
- in un archivio con plist backed.
Ma non con l'utente creato sopra. Le preferenze non vengono mai salvate. So che esiste un servizio che mantiene sincronizzate le preferenze con la memoria e il filesystem (non è in esecuzione per il nuovo utente).
La domanda è: cosa c'è di sbagliato in Java - cosa servirebbe per correggerlo - o con il modo in cui l'utente del sistema è stato creato.
Anche un semplice programma java come il seguente non innesca la possibilità di scrivere le preferenze:
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
public class prefTest {
public static void main( String[] args ) throws BackingStoreException {
System.out.println( System.getProperty( "user.home" ) );
Preferences userRoot = Preferences.userRoot();
userRoot.put( "Test", "Value" );
userRoot.flush();
System.out.println( userRoot.get( "Test", "DEFAULT" ) );
}
}
L'esecuzione di questo programma con l'utente del servizio genererà un output errato e non creerà un file delle preferenze Java per l'aggiornamento di un file esistente.