Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add two facts: libjvm and java executable paths #117

Merged
merged 1 commit into from
Dec 1, 2015

Conversation

faxm0dem
Copy link
Contributor

@faxm0dem faxm0dem commented May 5, 2015

It's complicated to automatically determine the location of libjvm.so. Neither openjdk nor oracle packages provide hints for ld.so.conf.d. The path to the java executable is just a byproduct than I thought could be useful.

@riton
Copy link

riton commented May 5, 2015

👍 for the libjvm.so path.

java_path = Facter.value(:java_path)
java_package = Facter::Util::Resolution.exec('dpkg -S '+java_path).split(':').first
#Facter::Util::Resolution.exec('dpkg -L '+java_package+' | grep libjvm.so\$').lines.first.strip
Facter::Util::Resolution.exec('dpkg -L '+java_package).lines.find_all { |l| l =~ /libjvm.so$/}.first.strip
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of doing find_all.first, why not just do find?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignorance!

@faxm0dem
Copy link
Contributor Author

faxm0dem commented May 6, 2015

Thanks for these constructive comments. I'll integrate them ASAP but currently I'm fighting with rspec: I just realized I was only testing the debian part in the test for libjvm fact, and now I'm trying to find a way to test both osfamilies. If you have any idea on how to test that without the confine :osfamily getting in the way, I'd be very grateful.

Edit: I just found this which should help
Edit2: This link was irrelevant. We can simply use before blocks here

@faxm0dem
Copy link
Contributor Author

faxm0dem commented May 6, 2015

It would maybe be more useful to have the dirname() of libjvm.so so that it could be used directly for LD_LIBRARY_PATH what do you think?

@riton
Copy link

riton commented May 6, 2015

I agree that the dirname() would be more useful for later use in ld.so.conf.d mechanisms (even if puppetlabs-stdlib already provides a dirname function)

@faxm0dem
Copy link
Contributor Author

I decided to go with the java_libjvm_path fact.
Can @elyscape or anybody else kindly review this?
I'd be happy to rebase this to a single commit if needed

@faxm0dem
Copy link
Contributor Author

Hi is there anything else I can do to have this merged?

@hunner
Copy link
Contributor

hunner commented Nov 5, 2015

Hi! Could you explain why the path to libjvm.so is useful? Is this something that is generally needed, or is there some special case that this is for? Also is it possible to use some generic method like ldd instead of rpm and dpkg?

@faxm0dem
Copy link
Contributor Author

faxm0dem commented Nov 6, 2015

Sure thing!
The main use-case for this is to add the path to ld.so.conf so that the dynamic linker will find it.
We're using it for instance for syslog-ng which has a java destination since 3.7.1.

So why do we need to do this?

  • no java distribution that I know of puts libjvm.so in the right place
  • no java distribution I know of provides a /etc/ld.so.conf.d/java.conf

Unfortunately, I have no better way to find its location apart from using the local packager or find.
Ideas welcome!

Facter.add(:java_path) do
setcode do
if Facter::Util::Resolution.which('readlink')
Facter::Util::Resolution.exec('readlink -e /usr/bin/java').strip
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will not work on Darwin, or FreeBSD or OpenBSD

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patches welcome!
But you're right the code should probably be confined

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... or Windows. Please just add the confine to :kernel => "Linux" if you do not want to support other platforms (which is totally fine with me!)

@faxm0dem faxm0dem force-pushed the f/libjvm_fact branch 2 times, most recently from 8562fd9 to 7510f4c Compare November 27, 2015 12:27
@faxm0dem
Copy link
Contributor Author

I confined the java_path fact to linux and fixed the unit tests.
I'd be delighted if any rspec-guru could review the latter, especially 7510f4c

Cheers

if java_path.empty?
nil
elsif Facter::Util::Resolution.which('dpkg')
java_package = Facter::Util::Resolution.exec('dpkg -S '+java_path).split(':').first
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You missed one string concatenation here.

@faxm0dem
Copy link
Contributor Author

thanks!

@DavidS
Copy link
Contributor

DavidS commented Nov 27, 2015

The tests look OK to me. There is still a minor comment outstanding on the coding style.

On a higher level, I'm wondering whether there is a reason not to use Dir.glob("#{basedir}/lib/**/libjvm.so") to find the libjvm.so (with basedir being the parent of dirname(readlink -f /usr/bin/java))? That should be much quicker than having to hit the package database.

@DavidS
Copy link
Contributor

DavidS commented Nov 27, 2015

On a more organizational note, pleas add a short description of the facts to the README (there's already some described there) and squash everything into a single commit, to keep the history clean!

@faxm0dem
Copy link
Contributor Author

I was unaware of the existence of ** and have to admit I wanted to avoid to implement this myself.
That light being shed on my knowledge, I will do some research on the performance implications of pkg vs. recursive glob

@faxm0dem
Copy link
Contributor Author

I added the implementation proposed by @DavidS as default resolution, so I can keep the rpm/deb based implementation in case the former is failing.
I now have to find a way to integrate this into the unit tests, and as of now have no idea on how to do that.
Anybody have an idea on how to rspec facts with multiple resolutions?

@DavidS
Copy link
Contributor

DavidS commented Nov 30, 2015

In what case would you expect the rpm/dpkg based variant to succeed when the globbing one doesn't?

I've also read a bit through the java docs, and it seems that moving the dirname(dirname(bin)) into java_path and calling it java_home would match people's expectations better? e.g. http://gedankenverlust.blogspot.de/2012/05/java-environment-variables-definitive.html :

User variable JAVA_HOME: de-facto convention used by some Java programs, especially Tomcat, to point to the JDK base folder.

Thank you for your patience and support in getting the best possible solution here!

@faxm0dem
Copy link
Contributor Author

here's what I found googling:

  • JAVA_HOME: must point to installation directory of JDK.
  • JRE_HOME: must point to installation directory of JRE.
  • CLASSPATH: contains libraries path which JVM will look for.

The java executable being provided by jre, JRE_HOME would IMHO be more suited instead of JAVA_HOME for locating the java binary. That being said, having both variables available would probably be useful.

Problem is, I'm no java expert, so maybe we should ask one :)

@DavidS
Copy link
Contributor

DavidS commented Nov 30, 2015

So I talked to two of our java devs and the base directory we're talking about is the java "home". Given that we're talking about the system default and to avoid any misunderstandings I'd recommend calling the fact "java_default_home" or "java_system_home" and return the dirname(dirname(readlink(usr/bin/java))). That way it is useful on its own.

@faxm0dem
Copy link
Contributor Author

is this what you'd like?

Example

java_default_home => '/usr/lib/jvm/java-8-openjdk-amd64/jre'

@DavidS
Copy link
Contributor

DavidS commented Nov 30, 2015

java_default_home => '/usr/lib/jvm/java-8-openjdk-amd64'

All the other directories below it (/lib, /bin, /jre/lib and /jre/bin) are the same across java versions.

@faxm0dem
Copy link
Contributor Author

I wouldn't use home then as ppl would mistake it for java_home which is home of the JDK, not its parent

@DavidS
Copy link
Contributor

DavidS commented Nov 30, 2015

the jre_home is usually java_home/jre

@faxm0dem
Copy link
Contributor Author

I'll go for this

java_default_home => '/usr/lib/jvm/java-8-openjdk-amd64'

as for the multiple resolutions, I think it's always a good thing to have a fallback method, especially now that it's already there and tested. If you prefer to keep things simple though, I'll remove the deb/rpm based ones.

@faxm0dem
Copy link
Contributor Author

faxm0dem commented Dec 1, 2015

@DavidS please advise on the last open quesion: do you want to keep the alternate package resolutions of libjvm.so or do you prefer to drop them?

@DavidS
Copy link
Contributor

DavidS commented Dec 1, 2015

@faxm0dem Personally I'd prefer to leave the code out as long as there is not a immediate use-case for it.

* dirname containing base directory of java
* e.g. java binary is `${::java_default_home}/jre/bin/java`

* dirname containing `libjvm.so`
* Most people will use this for LD_LIBRARY_PATH
@faxm0dem
Copy link
Contributor Author

faxm0dem commented Dec 1, 2015

@DavidS all right, please review

DavidS added a commit that referenced this pull request Dec 1, 2015
add two facts: libjvm and java executable paths
@DavidS DavidS merged commit 4764484 into puppetlabs:master Dec 1, 2015
@DavidS
Copy link
Contributor

DavidS commented Dec 1, 2015

Thank you for your work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants