_jvmfinder.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #*****************************************************************************
  2. # Copyright 2013 Thomas Calmant
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. #*****************************************************************************
  17. import os
  18. # ------------------------------------------------------------------------------
  19. class JVMNotFoundException(RuntimeError):
  20. pass
  21. class JVMNotSupportedException(RuntimeError):
  22. pass
  23. class JVMFinder(object):
  24. """
  25. JVM library finder base class
  26. """
  27. def __init__(self):
  28. """
  29. Sets up members
  30. """
  31. # Library file name
  32. self._libfile = "libjvm.so"
  33. # Predefined locations
  34. self._locations = ("/usr/lib/jvm", "/usr/java")
  35. # Search methods
  36. self._methods = (self._get_from_java_home,
  37. self._get_from_known_locations)
  38. def find_libjvm(self, java_home):
  39. """
  40. Recursively looks for the given file
  41. :param java_home: A Java home folder
  42. :param filename: Name of the file to find
  43. :return: The first found file path, or None
  44. """
  45. found_jamvm = False
  46. non_supported_jvm = ('cacao', 'jamvm')
  47. found_non_supported_jvm = False
  48. # Look for the file
  49. for root, _, names in os.walk(java_home):
  50. if self._libfile in names:
  51. # Found it, but check for non supported jvms
  52. candidate = os.path.split(root)[1]
  53. if candidate in non_supported_jvm:
  54. found_non_supported_jvm = True
  55. continue # maybe we will find another one?
  56. return os.path.join(root, self._libfile)
  57. else:
  58. if found_non_supported_jvm:
  59. raise JVMNotSupportedException("Sorry '{0}' is known to be "
  60. "broken. Please ensure your "
  61. "JAVA_HOME contains at least "
  62. "another JVM implementation "
  63. "(eg. server)"
  64. .format(candidate))
  65. # File not found
  66. raise JVMNotFoundException("Sorry no JVM could be found. "
  67. "Please ensure your JAVA_HOME "
  68. "environment variable is pointing "
  69. "to correct installation.")
  70. def find_possible_homes(self, parents):
  71. """
  72. Generator that looks for the first-level children folders that could be
  73. Java installations, according to their name
  74. :param parents: A list of parent directories
  75. :return: The possible JVM installation folders
  76. """
  77. homes = []
  78. java_names = ('jre', 'jdk', 'java')
  79. for parent in parents:
  80. for childname in sorted(os.listdir(parent)):
  81. # Compute the real path
  82. path = os.path.realpath(os.path.join(parent, childname))
  83. if path in homes or not os.path.isdir(path):
  84. # Already known path, or not a directory -> ignore
  85. continue
  86. # Check if the path seems OK
  87. real_name = os.path.basename(path).lower()
  88. for java_name in java_names:
  89. if java_name in real_name:
  90. # Correct JVM folder name
  91. homes.append(path)
  92. yield path
  93. break
  94. def get_jvm_path(self):
  95. """
  96. Retrieves the path to the default or first found JVM library
  97. :return: The path to the JVM shared library file
  98. :raise ValueError: No JVM library found
  99. """
  100. for method in self._methods:
  101. try:
  102. jvm = method()
  103. except NotImplementedError:
  104. # Ignore missing implementations
  105. pass
  106. except JVMNotFoundException:
  107. # Ignore not successful methods
  108. pass
  109. else:
  110. if jvm is not None:
  111. return jvm
  112. else:
  113. raise JVMNotFoundException("No JVM shared library file ({0}) "
  114. "found. Try setting up the JAVA_HOME "
  115. "environment variable properly."
  116. .format(self._libfile))
  117. def _get_from_java_home(self):
  118. """
  119. Retrieves the Java library path according to the JAVA_HOME environment
  120. variable
  121. :return: The path to the JVM library, or None
  122. """
  123. # Get the environment variable
  124. java_home = os.getenv("JAVA_HOME")
  125. if java_home and os.path.exists(java_home):
  126. # Get the real installation path
  127. java_home = os.path.realpath(java_home)
  128. # Look for the library file
  129. return self.find_libjvm(java_home)
  130. def _get_from_known_locations(self):
  131. """
  132. Retrieves the first existing Java library path in the predefined known
  133. locations
  134. :return: The path to the JVM library, or None
  135. """
  136. for home in self.find_possible_homes(self._locations):
  137. jvm = self.find_libjvm(home)
  138. if jvm is not None:
  139. return jvm