2017-09-11 5 views
-1

J'ai cette méthode qui ne fonctionne que sous Windows et utilise des classes de sun.awt.shell, cependant l'application peut fonctionner sur des systèmes non-windows, et sur Java, il peut être utilisé avec OpenSdk et je suppose que cela n'inclut pas la classe sun.awt.shell.Comment écrire une classe java si la classe de références n'existe pas sur certains systèmes

J'ai supprimé les instructions d'importation sun.awt.shell de la classe afin que le nom de classe ne soit référencé que dans cette méthode, et je peux garantir que cette méthode ne sera jamais réellement exécutée sur une machine non-Windows.

Mais est-ce suffisant ou la classe ne parviendra-t-elle pas à se charger de toute façon sur les systèmes qui manquent ces classes, ai-je besoin de réécrire la méthode pour utiliser la réflexion?

public static boolean isRemote(String newPath) 
    { 
     try 
     { 
      Path root = Paths.get(newPath).getRoot(); 
      sun.awt.shell.ShellFolder shellFolder = sun.awt.shell.ShellFolder.getShellFolder(root.toFile()); 
      sun.awt.shell.ShellFolderColumnInfo[] cols = shellFolder.getFolderColumns(); 
      for (int i = 0; i < cols.length; i++) 
      { 
       if (cols[i].getTitle().equals(WINDOWS_SHELL_SIZE) 
         && ((String) shellFolder.getFolderColumnValue(i)).startsWith("Network Drive")) 
       { 
        return true; 
       } 
       else if (cols[i].getTitle().equals(WINDOWS_SHELL_ATTRIBUTES) 
         && ((String) shellFolder.getFolderColumnValue(i)).startsWith("\\")) 
       { 
        return true; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MainWindow.logger.log(Level.SEVERE, ex.getMessage(), ex); 
      return false; 
     } 
     return false; 
    } 
+0

pourquoi fermer, surtout sans raison! –

+0

"La classe ne parviendra-t-elle pas à charger de toute façon les systèmes qui manquent ces classes [...]?" Hé bien oui. En fait, votre classe ne manquera pas de charger. Ce qui échouera est un appel de méthode 'isRemote'. Si les classes du package 'sun.awt.shell' ne sont pas présentes lors de l'exécution, vous obtiendrez un' NoClassDefFoundError'. Cela n'a rien à voir avec l'instruction 'import' qui est une fonctionnalité de compilation uniquement. – Seelenvirtuose

+0

Pourriez-vous vérifier, par exemple par 'Class.forName (" sun.awt.shell.ShellFolder ")' et regarder pour ClassNotFoundException' avant de l'utiliser? – c0der

Répondre

0

La solution que je suis allé avec était simplement de mettre toutes les méthodes qui nécessitaient des classes uniquement disponibles sur Windows dans une classe. Alors je avant d'appeler une de ces méthodes constituent une autre classe il y avait toujours un contrôle pour assurer un fonctionnement sur le système d'exploitation Windows

i.e.

if(Platform.isWindows()) 
{ 
    return WindowsUtilsFS.isRemote(newPath) 
} 

donc par conséquent, la classe se jamais appelé ou chargé. J'ai déployé ceci dans la production et n'ai eu aucun rapport d'erreur ainsi je pense que cela fonctionne correctement.

0

Mais est-ce suffisant ou sera la classe ne parviennent pas à charger quand même sur les systèmes manquants ces classes.

Si les classes ne sont pas présentes lors de l'exécution, le programme échouera. Si vous utilisez des références compilées, vous obtiendrez généralement un NoClassDefFoundError lors du démarrage.

ai-je besoin de réécrire la méthode pour utiliser la réflexion?

La réflexion n'aiderait pas. Si vous essayez d'utiliser Class.forName pour charger la classe (par exemple), vous obtiendrez un ClassNotFoundException si la classe ne fait pas partie du JRE.


Je ne comprends pas bien ce que le code est en train de faire, mais il semble utiliser des mécanismes qui ne fonctionnerait pas sur un système Linux (par exemple). En effet, il n'y a pas vraiment de concept bien défini de fichier "distant" sur un système Linux.

Peut-être que cela vous aiderait si vous expliquiez pour quoi vous utilisiez cette méthode. Je suppose que c'est quelque chose qui n'a de sens que sur Windows.

En règle générale, vous devriez éviter en utilisant les classes sun.* parce que: - ils sont souvent OS plate-forme spécifique, et - ils sont susceptibles de changer, ou être retiré sans préavis.


Je comprends ce que vous demandez maintenant. Vous ne voulez pas vraiment isRemote de travailler sur des systèmes non-Windows.

Il y a deux alternatives:

  • Vous pouvez diviser cette méthode en deux parties, et utiliser le chargement de classe dynamique pour charger le système partie spécifique. Ou faites de la méthode isRemote une méthode dans un plug-in spécifique au système chargé dynamiquement. (Fondamentalement, la même idée ...) Dans les deux cas, la classe chargée dynamiquement peut appeler ShellFolder en utilisant des appels Java normaux.

  • Vous pouvez utiliser Class.forName("sun.awt.shell.ShellFolder") pour tenter de charger la classe, puis utiliser la réflexion pour appeler des méthodes.

Cependant, ma note sur sun.* est toujours valide. Sun/Oracle modifient ou suppriment souvent ces classes internes.

1 - Ou peut-être que vous le faites, mais vous vous résignez au fait que ce ne sera pas le cas.

+0

Vous m'avez mal compris Je compile le code sur Windows puis il est déployé sur Windows, OSX, Linux ectera. Je sais que cette méthode ne fonctionnera pas sous Linux, elle ne sera jamais appelée sur Linux pour une tâche particulière sur Windows, mais je ne veux pas avoir à faire des ajustements dans le système de construction juste pour cela. Mais la simple présence de cette méthode dans cette classe provoquera-t-elle des problèmes sur un système linux qui ne possède pas les classes shell de référence lorsque la classe est chargée en mémoire. –

+0

Oui. Je t'ai mal compris. –

+0

J'ai raison de dire que si je viens de déplacer cette méthode isRemote() dans une nouvelle classe qui ne contient que cette méthode. Puis, parce que isRemote() n'est jamais appelé sur un système, la classe ne sera jamais chargée et donc aucun problème. BTW Je préfère ne pas utiliser ces classes mais il semble qu'il n'y ait pas de solution en utilisant seulement Java générique - https://stackoverflow.com/questions/46077551/in-java-how-do-i-find-actual-path- de-remote-filesystem-mounted-on-windows –