Skip to content

Major overhaul of Java packages#8613

Merged
scheibelp merged 7 commits intospack:developfrom
adamjstewart:packages/jdk
Aug 28, 2018
Merged

Major overhaul of Java packages#8613
scheibelp merged 7 commits intospack:developfrom
adamjstewart:packages/jdk

Conversation

@adamjstewart
Copy link
Copy Markdown
Member

@adamjstewart adamjstewart commented Jun 29, 2018

This PR includes the following changes:

The last point is still a work in progress. Bugs I've discovered so far:

  1. It is not possible to write extends('java'), you have to write extends('jdk') or extends('icedtea'). It seems that virtual providers are not extendable. This is important not only for Java, but also for Python. Someday we would like Python to become a virtual provider for CPython, Intel Python, PyPy, IronPython, etc. See Python as a virtual dependency #7966.
  2. Packages cannot extend multiple packages: Allow packages to extend multiple other packages #987.
  3. In order to activate/deactive a Java extension, we need to symlink all *.jar files to spec['java'].lib.ext. How do I do this? I only know how to merge the two installation prefixes. I guess I could start installing .jar files to prefix.lib.ext instead of prefix...

@hartzell I was looking through #4386. I'm guessing you have a lot more Java experience than me. Can you take a look at this?
@snehring It looks like you wrote the icedtea package. Is it actually working? Would you like me to make similar changes to icedtea as well, so things like spec['java'].home and spec['java'].libs work no matter what Java provider you are using?


homepage = "http://www.oracle.com/technetwork/java/javase/downloads/index.html"

maintainers = ['justintoo']
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@justintoo I noticed you listed yourself as an author of this package above. Spack now has the ability to list maintainers of a package. Would you like to be added so that you are pinged whenever a major change to the package is made?

version('1.8.0_92-b14', '65a1cc17ea362453a6e0eb4f13be76e4', curl_options=curl_options)
version('1.8.0_73-b02', '1b0120970aa8bc182606a16bf848a686', curl_options=curl_options)
version('1.8.0_66-b17', '88f31f3d642c3287134297b8c10e61bf', curl_options=curl_options)
version('1.7.0_80-b0', '6152f8a7561acf795ca4701daa10a965', curl_options=curl_options)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

None of these older versions are downloadable, so I removed the url_for_version function. Do we even want to keep these versions?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm no longer at that particular consulting gig, but I used to have the tarballs for a couple of those versions (b14 and b17, perhaps) in mirrors that were used for repeatable deployments.

I'm generally not in favor of cleaning them up (this came up in the Perl package too), it breaks things for people using mirrors and then we need to re-instate them.

if os.path.exists(java_home):
java_home = Executable(java_home)
version = str(self.version.up_to(2))
prefix = java_home('--version', version, output=str).strip()
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Technically, this isn't perfect. If someone has multiple versions of JDK 10.0 installed, it will return the newest version.


Search recursively to find the correct library location."""

return find_libraries(['libjvm'], root=self.home, recursive=True)
Copy link
Copy Markdown
Member Author

@adamjstewart adamjstewart Jun 29, 2018

Choose a reason for hiding this comment

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

I'm not sure if libjvm is the prototypical Java library. There is also a libjava. But I needed libjvm for another package (#8614).


@run_before('install')
def macos_check(self):
if self.spec.satisfies('platform=darwin'):
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I could have used conflicts for this, but if I did, you would not be able to install the package, even if it is already available as an external package.

[email protected]_45-b18: /path/to/jdk/Home
buildable: False""".format(self.homepage)

tty.die(msg)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Unfortunately, this message does not print to the terminal unless you are installing with --verbose. It will end up in your build log. See #2566.

def setup_dependent_package(self, module, dependent_spec):
"""Allows spec['java'].home to work."""

self.spec.home = self.home
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Most of the logic in these last couple functions is stolen from the python package.

def setup_environment(self, spack_env, run_env):

env['JAVA_HOME'] = self.spec['java'].prefix
# spack_env.set('JAVA_HOME', self.spec['jdk'].prefix)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This variable should already be set by setup_dependent_environment in the jdk and icedtea packages.

@snehring
Copy link
Copy Markdown
Contributor

@adamjstewart it did work at one point, but it seems to be having issues with some X libraries at the moment (on my desktop at least). Feel free to make the change to the icedtea package, I'll probably revisit it before long to try to fix it up.

@adamjstewart adamjstewart changed the title Major overhaul of JDK package Major overhaul of Java packages Jul 4, 2018
@adamjstewart
Copy link
Copy Markdown
Member Author

Ping.

@hartzell
Copy link
Copy Markdown
Contributor

@hartzell I was looking through #4386. I'm guessing you have a lot more Java experience than me. Can you take a look at this?

Actually, I don't do Java (or [wW]indows...). #4386 was me asking if the Spack community would let me get away with plopping a .jar file into place or whether I was expected to build it from src via maven or some such. I wouldn't use Spack to install e.g. vim by untarr'ing their binary tarball and I've been a supporter of building go via the old v1.4 bootstrapping tree (the last release that built from C) but I was relieved to discover that the Java-using community works different(TM).

Only useful feedback I have (commented inline) is that deleting information about old releases, even if they're no longer downloadable, will bork people who have them in mirrors for reproducibilities sake.

matz-e added a commit to BlueBrain/spack that referenced this pull request Jul 23, 2018
Previous builds return 404s. This commit will have to be dropped from
our tree once spack#8613 is merged.
matz-e added a commit to BlueBrain/spack that referenced this pull request Jul 23, 2018
Previous builds return 404s. This commit will have to be dropped from
our tree once spack#8613 is merged.
pramodk pushed a commit to BlueBrain/spack that referenced this pull request Aug 1, 2018
Previous builds return 404s. This commit will have to be dropped from
our tree once spack#8613 is merged.
url='http://icedtea.wildebeest.org/download/drops/icedtea8/3.4.0/shenandoah.tar.xz',
when='@3.4.0')

# FIXME:
Copy link
Copy Markdown
Member

@scheibelp scheibelp Aug 9, 2018

Choose a reason for hiding this comment

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

If I understand, only one of (1) or (2) needs to happen to support this.

Regarding (3), is that strictly required? Do all packages which depend on java want to add their jars to spec['java'].prefix.lib.ext? This isn't how Java projects are typically exposed to the user (generally they would all be added to the classpath, which could be managed by adding a JavaPackage build system). In other words, I'm not sure if packages using Java would typically want to extend Java.

If that is still desirable, then while the lack of virtual extensions would make it hard to activate the package (by modifying the Spack Java package prefix), you could achieve this relocation for views: PackageViewMixin.view_destination/view_source may be useful here. Once those are implemented and working for views, activations should automatically work too once (1) or (2) is resolved.

I'll be looking through this more tomorrow.

Copy link
Copy Markdown
Member Author

@adamjstewart adamjstewart Aug 9, 2018

Choose a reason for hiding this comment

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

(1) and (2) have nothing in common. (1) is "you can't extend virtual packages" and (2) is "you can't extend multiple packages". Although, maybe (1) is another symptom of (2)? Anyway, (2) will be really important if we ever make python a virtual package.

(3) is not strictly required. You're right, Java developers rarely suggest installing .jar files directly to lib/ext. But it does work, so if it isn't too much work, I might as well support it. I'm sure there's an easy way to do this, I just don't know how.

The main reason why packages would want to extend Java is so that they are automatically added to the CLASSPATH. I implemented things just like python did, but I guess I could add them to CLASSPATH if they have a run-time dep on Java, not only if they are extensions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(1) and (2) have nothing in common. (1) is "you can't extend virtual packages" and (2) is "you can't extend multiple packages"

What I mean is: if you could extend multiple packages, my understanding is you would say

extends('jdk')
extends('icedtea')

And you wouldn't need to add extends('java').

That being said, the primary benefits of marking a package as an extension of some other package is:

  • The dependent can be activated in the prefix of the extendee
  • You can manage centralized state (e.g. a merged .pth file for Python)

Since Java doesn't need to manage centralized state for dependents, only the first benefit would apply. As mentioned in #8613 (comment), you can implement whatever customized merging logic you want without waiting for the extension issues to be resolved.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

if you could extend multiple packages, my understanding is you would say

extends('jdk')
extends('icedtea')

And you wouldn't need to add extends('java').

That won't work, as the package would now depend on both jdk and icedtea. Virtual packages exist for a reason 😆

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm doing a bad job of inferring why you want this so I'll be direct: why is the ability to extend multiple packages important here? Could you give me an example of what you would write if this were possible?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See #987. There are already multiple packages in Spack that extend multiple languages. For example, some packages have both Python and Perl libraries.

@scheibelp
Copy link
Copy Markdown
Member

Made java extendable
The last point is still a work in progress.

Do you want to see this merged before progress is made on 1/2?

I had never heard of lib/ext and don't think most people would know to make use of it, so I'm not sure if it's important to focus on that, since users would likely be more interested in automatically setting up the classpath.

If that is still desirable (to expand on #8613 (comment)): customizing the linking logic, Spack doesn't go through Package.activate, you override functions that are available to all packages (not just extensions). If you want to take just the lib/ directory of a java-dependent package (e.g. elasticsearch) and add it to lib/ext/ (of the view prefix or - for an activation - the jdk install prefix) you could add:

def view_source(self):
  return self.spec.prefix.lib

def view_destination(self, view):
  return join_path(view.root, 'lib/ext')

If you want to do that in addition to adding <elastic search prefix>/bin/ to <view prefix>/bin/, that would require changing the view API (which I can do).

@adamjstewart
Copy link
Copy Markdown
Member Author

Do you want to see this merged before progress is made on 1/2?

I would be fine with that. #8614 is all I really needed this PR for, and it works for me. (1) is a bigger issue than (2); there are more packages that need to extend Java (and will someday need to extend Python) than there are that extend multiple languages. But both need to be solved someday. We can't keep ignoring them. I opened the issue for (2) over 2 years ago 😢

Let me try out your suggestion for (3). Are you suggesting that .jar files should be installed to prefix.lib? In #8614 I just installed them to prefix. Other PRs have been installing them to prefix.bin.

@scheibelp
Copy link
Copy Markdown
Member

Let me try out your suggestion for (3). Are you suggesting that .jar files should be installed to prefix.lib?

I was assuming that the jar files were installed to prefix.lib. If they are just installed to prefix, then you should not have to define view_source.

@adamjstewart
Copy link
Copy Markdown
Member Author

I mean, I can install them anywhere, there is no underlying build system, so I'm not sure where these kind of things should be installed by default. @hartzell has installed a lot of things to prefix.bin, but those were mostly .jar files that had an entrypoint and could be run from the command-line, they weren't libraries.

@scheibelp
Copy link
Copy Markdown
Member

As I think more on this, IMO a classpath-oriented approach would be better than linking to lib/ext/

To get a sense of how diverse the installations are, I've looked through several Java-dependent packages (ant, hadoop, and to a lesser extent maven and spark) and I get the impression most of them would run into the problem described at the end of #8613 (comment): view_source and view_destination are really just ways to select a subset of the installation or redirect the entire linking to a relative directory.

My guess is that you'd want to preserve the original install structure but to potentially add ext/lib/ when activating or adding to a view (since changing it may require care to ensure that CLASSPATH isn't wrong). That should still be accomplished with PackageViewMixin but that class isn't yet sophisticated enough to support it. Which is to say that (3) should be rewritten:

  1. Override activate and deactivate to symlink all .jar files to /lib/ext

changes to

  1. Update PackageViewMixin to support taking a given source file and symlinking it in two locations (e.g. so jar files can appear in lib/ext)

But this would be similar to offering an option to set up the classpath, which would be more familiar. Java-dependent packages which just install jars could use the method suggested in #8613 (comment), but that wouldn't help with perhaps many Java packages.

Regarding:

In #8614 I just installed them to prefix. Other PRs have been installing them to prefix.bin.

Could you mention a few examples of the latter?

@adamjstewart
Copy link
Copy Markdown
Member Author

Could you mention a few examples of the latter?

  • astral
  • gatk
  • genomefinisher
  • haploview
  • igv
  • igvtools
  • pgdspider
  • picard
  • pilon
  • qorts
  • rdp-classifier
  • rna-seqc
  • snpeff
  • trimmomatic
  • varscan

@adamjstewart
Copy link
Copy Markdown
Member Author

Ping @scheibelp. I think it's safe to merge this PR as is until we figure out (1)-(3).

# FIXME:
# 1. `extends('java')` doesn't work, you need to use `extends('icedtea')`
# 2. Packages cannot extend multiple packages, see #987
# 3. Override activate and deactivate to symlink all .jar files to
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@adamjstewart could you rewrite (3) according to #8613 (comment) (or use the wording suggested there)? The way it's worded now, it looks like something a package author could manage, but I think it will actually take some work on the core (e.g. updating PackageViewMixin to add a symlink to the jar files in lib/ext).

Other than that this looks good.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

My guess is that you'd want to preserve the original install structure but to potentially add ext/lib/

I'm not sure if this is the case here. Honestly, we both agree that symlinking .jar files to ext/lib probably isn't a good idea, but if we were to support it, I would expect spack activate to only symlink .jar files to ext/lib, not anywhere else. Some PRs install them in prefix.bin, others in prefix.lib or prefix. It wouldn't make sense in my mind to symlink to the Java prefix.bin or prefix.lib directories when prefix.ext.lib is designed for this purpose.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would expect spack activate to only symlink .jar files to ext/lib, not anywhere else.

OK fair enough. My main point though is that Package.activate wouldn't be the natural place to handle that anymore: it should be handled by adding a method to PackageViewMixin and to have YamlFilesystemView.merge check for customized Package merging behavior and use it if present, for example if a java package wants to add .jar files to ext/lib/ and also add a script to prefix.bin. Another possible way to word it:

# TODO: update YamlFilesystemView.merge to allow a Package to
# completely override how it is symlinked into a view prefix

@scheibelp scheibelp merged commit be42b8d into spack:develop Aug 28, 2018
@scheibelp
Copy link
Copy Markdown
Member

Thanks!

@adamjstewart adamjstewart deleted the packages/jdk branch August 28, 2018 19:43
ptbremer pushed a commit to ptbremer/spack that referenced this pull request Aug 31, 2018
This PR includes the following changes:

* Added JDK 10
* Changed the JDK version numbers according to the consensus reached
  in spack#2284
* Added spec['java'].home and spec['java'].libs, similar to spack#3367
  (JDK and IcedTea)
* Added a check to prevent people from installing JDK on macOS
* Set CLASSPATH for packages depending on Java (JDK and IcedTea)
* Add TODO for extending virtual packages (not currently possible)
* Add TODO for adding Java dependents to views
* Add TODO for packages which extend multiple packages (e.g. Java
  and Python)
anderson2981 pushed a commit to anderson2981/spack that referenced this pull request Sep 7, 2018
This PR includes the following changes:

* Added JDK 10
* Changed the JDK version numbers according to the consensus reached
  in spack#2284
* Added spec['java'].home and spec['java'].libs, similar to spack#3367
  (JDK and IcedTea)
* Added a check to prevent people from installing JDK on macOS
* Set CLASSPATH for packages depending on Java (JDK and IcedTea)
* Add TODO for extending virtual packages (not currently possible)
* Add TODO for adding Java dependents to views
* Add TODO for packages which extend multiple packages (e.g. Java
  and Python)
pramodk pushed a commit to BlueBrain/spack that referenced this pull request Sep 29, 2018
Previous builds return 404s. This commit will have to be dropped from
our tree once spack#8613 is merged.
ptbremer pushed a commit to ptbremer/spack that referenced this pull request Oct 12, 2018
This PR includes the following changes:

* Added JDK 10
* Changed the JDK version numbers according to the consensus reached
  in spack#2284
* Added spec['java'].home and spec['java'].libs, similar to spack#3367
  (JDK and IcedTea)
* Added a check to prevent people from installing JDK on macOS
* Set CLASSPATH for packages depending on Java (JDK and IcedTea)
* Add TODO for extending virtual packages (not currently possible)
* Add TODO for adding Java dependents to views
* Add TODO for packages which extend multiple packages (e.g. Java
  and Python)
pramodk pushed a commit to BlueBrain/spack that referenced this pull request Nov 10, 2018
Previous builds return 404s. This commit will have to be dropped from
our tree once spack#8613 is merged.
pramodk pushed a commit to BlueBrain/spack that referenced this pull request Nov 27, 2018
Previous builds return 404s. This commit will have to be dropped from
our tree once spack#8613 is merged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants