gliderlabs / docker-alpine

Alpine Linux Docker image. Win at minimalism!
http://gliderlabs.viewdocs.io/docker-alpine
BSD 2-Clause "Simplified" License
5.71k stars 531 forks source link

Alpine libs not compatible with Java 8 #11

Closed giovannicandido closed 8 years ago

giovannicandido commented 9 years ago

Trying to install oracle JDK 8 and I get this error when run:

. /opt/jdk/bin/java -version /bin/ash: /opt/jdk/bin/java: : not found /bin/ash: /opt/jdk/bin/java: : not found @@@@@@@?@@@@ |?@@DDP?td??@?@1Q?t/lib64/ld-linux-x86-64.so.2GNU GNU?t?)N?ݓ??;r?Z???h nonexistent directory /bin/ash: /opt/jdk/bin/java: line 1: ELF: not found /bin/ash: /opt/jdk/bin/java: ?: not found /bin/ash: /opt/jdk/bin/java: line 3: ?: not found /bin/ash: /opt/jdk/bin/java: syntax error: unexpected end of file (expecting ")")

The ldd command give the result:

ldd /opt/jdk/bin/java
    /lib64/ld-linux-x86-64.so.2 (0x7f8da09f8000)
    libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f8da09f8000)
    libjli.so => /opt/jdk/bin/../lib/amd64/jli/libjli.so (0x7f8da07e0000)
    libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7f8da09f8000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f8da09f8000)
Error relocating /opt/jdk/bin/../lib/amd64/jli/libjli.so: __rawmemchr: symbol not found

What could be done?

frol commented 8 years ago

@elsmorian I am happy that you considered Alpine as a base image for your images. I would like to start with a warning: glibc on Alpine Linux should be considered as a hack! While it is acceptable to use glibc on Alpine, it is a hard way. I, personally, use alpine-glibc in production, but there are cases when it makes life dreadful (e.g. when you integrate a weird proprietary binaries, or deploy anything with "smart" licensing). You have to use glibc-targeted compilers (there is gcc in Anaconda repos, but it is not considered as a best practice at all, still, I use it, and even maintain gcc-5 and gcc-6), and you should use glibc-compiled libraries (again, there are almost all of them in Anaconda). In the end, you will use not much of Alpine, which is a bit awkward. Good luck!)

And has this meant that any program run in these containers now runs against glibc?

No. Programs are fine, but, mixing shared libraries is very tricky (I don't exactly understand how, but sometimes this works fine). As a rule of thumb, try not to mix glibc and musl libc C extensions for Python modules.

jirutka commented 8 years ago

@elsmorian Why exactly do you need glibc on Alpine?

frol commented 8 years ago

@jirutka He pointed out the he wants to use Anaconda Python, which (binary) packages are build only against glibc. In fact, there is no need in glibc on Alpine; our need is mostly about small footprint image and glibc requirement. I guess, busybox would suit better here, but, unfortunately, it was killed :(

jirutka commented 8 years ago

@frol We can just make Alpine package for Anaconda (build from source against musl), can’t we?

frol commented 8 years ago

@jirutka You will have to start with compilation of Python (or try to trick conda to use system Python distribution (which is not a bad idea, by the way)). Next, you recompile all binary packages. BTW, Anaconda has just recently opened some recipes into conda-forge initiative, yet they are still work in progress. Thus, yes, it is possible to build Anaconda infrastructure for musl, but it is a huge effort.

elsmorian commented 8 years ago

@jirutka @frol Thanks for the info. Tricking conda into using Python already on the system is interesting but means you loose out on its abilities to pull in any version of python you want per env.

It would be great to have anaconda builds without glibc, but because of it being binary focused, you would have to rebuild all the packages :/

This seems to be working so far, will keep you updated!

PatrickHuetter commented 8 years ago

+1

day0ops commented 8 years ago

Trying to run a node-oracledb project in Alpine with glibc libraries causes a number of symbol not found errors. Did anyone get it going ?

Error: Error relocating /opt/oracle/drivers/instantclient/libclntsh.so.11.1: getcontext: symbol not found
    at Error (native)
    at Object.Module._extensions..node (module.js:568:18)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (node_modules/oracledb/lib/oracledb.js:32:19)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (node_modules/oracledb/index.js:1:80)

What im thinking of doing is now is,

  1. Installing glibc
  2. Building Node and Python against glibc
  3. And building the project specific libraries such as node-oracledb against glibc

Any thoughts anyone ?

tpischke commented 8 years ago

The link to glibc seems to be dead. Any alternative source that works?

I tried here, but installing it didn't fix the original problem:
https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.21-r2/glibc-2.21-r2.apk

tpischke commented 8 years ago
FROM alpine:3.2

# Install cURL
RUN apk --update add wget curl ca-certificates tar && \
    curl -Ls https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.21-r2/glibc-2.21-r2.apk > glibc.apk && \
    apk add --allow-untrusted glibc.apk

# Java Version
ENV JAVA_VERSION_MAJOR 8
ENV JAVA_VERSION_MINOR 45
ENV JAVA_VERSION_BUILD 14
ENV JAVA_PACKAGE       jdk

# Download and unarchive Java
RUN mkdir /opt && curl -jksSLH "Cookie: oraclelicense=accept-securebackup-cookie"\
  http://download.oracle.com/otn-pub/java/jdk/${JAVA_VERSION_MAJOR}u${JAVA_VERSION_MINOR}-b${JAVA_VERSION_BUILD}/${JAVA_PACKAGE}-${JAVA_VERSION_MAJOR}u${JAVA_VERSION_MINOR}-linux-x64.tar.gz \
    | tar -xzf - -C /opt &&\
    ln -s /opt/jdk1.${JAVA_VERSION_MAJOR}.0_${JAVA_VERSION_MINOR} /opt/jdk &&\
    rm -rf /opt/jdk/*src.zip \
           /opt/jdk/lib/missioncontrol \
           /opt/jdk/lib/visualvm \
           /opt/jdk/lib/*javafx* \
           /opt/jdk/jre/lib/plugin.jar \
           /opt/jdk/jre/lib/ext/jfxrt.jar \
           /opt/jdk/jre/bin/javaws \
           /opt/jdk/jre/lib/javaws.jar \
           /opt/jdk/jre/lib/desktop \
           /opt/jdk/jre/plugin \
           /opt/jdk/jre/lib/deploy* \
           /opt/jdk/jre/lib/*javafx* \
           /opt/jdk/jre/lib/*jfx* \
           /opt/jdk/jre/lib/amd64/libdecora_sse.so \
           /opt/jdk/jre/lib/amd64/libprism_*.so \
           /opt/jdk/jre/lib/amd64/libfxplugins.so \
           /opt/jdk/jre/lib/amd64/libglass.so \
           /opt/jdk/jre/lib/amd64/libgstreamer-lite.so \
           /opt/jdk/jre/lib/amd64/libjavafx*.so \
           /opt/jdk/jre/lib/amd64/libjfx*.so

# Set environment
ENV JAVA_HOME /opt/jdk
ENV PATH ${PATH}:${JAVA_HOME}/bin
docker run -it java /bin/sh
/ # . /opt/jdk/bin/java -version
/bin/sh: /opt/jdk/bin/java: : not found
/bin/sh: /opt/jdk/bin/java: : not found
@@@@@@@��@@@@ |� @@DDP�td��@�@1Q�td/lib64/ld-linux-x86-64.so.2GNU  GNU�t�)N�ݓ��;r�Z��?h: nonexistent directory
/bin/sh: /opt/jdk/bin/java: line 1: ELF: not found
/bin/sh: /opt/jdk/bin/java: �: not found
/bin/sh: /opt/jdk/bin/java: line 3: �: not found
/bin/sh: /opt/jdk/bin/java: syntax error: unexpected end of file (expecting ")")
frol commented 8 years ago

@tpischke Why on Earth do you still use 2.21? The project has stabilized on 2.23-r3 and has been transferred to @sgerrand https://github.com/sgerrand/alpine-pkg-glibc/releases. Anyway, just use frolvlad/alpine-glibc or at least just copy the Dockerfile if you don't want to have "external dependency".

P.S. If you need OracleJDK 8, go and have it: frolvlad/alpine-oraclejdk8

tpischke commented 8 years ago

I was just following this;

https://developer.atlassian.com/blog/2015/08/minimal-java-docker-containers/

@Tried 2.23-r2, same result.

Wasn't aware of frolvlad/alpine-glibc. Will give it a try.

tpischke commented 8 years ago

Same result with alpine-glibc. What am I missing?

frol commented 8 years ago

@tpischke Why do you try to source (. before the command) the Java binary as sh script? Just run it as

$ java -version
tpischke commented 8 years ago

Calling java directly didn't work for some reason with my original Dockerfile. Works beautifully with your image though. I'm up and running. Thanks for the help!

frol commented 8 years ago

@tpischke I still strongly recommend you use frolvlad/alpine-oraclejdk8 instead of crafting your own (the manuals are outdated and just useless)... There are slim, cleaned and full versions of the images, so you should be just fine.

jirutka commented 8 years ago

I very strongly recommend to use package openjdk8 instead of these nasty hacks. If some software doesn’t run on OpenJDK and does on Oracle JDK (which is quite rare), then fix that software instead of crippling Alpine.

tpischke commented 8 years ago

Can the java version be specified? We test and recommend specific java versions to our customers. Also, 'unofficial' external dependencies are forbidden by the project lead.

tpischke commented 8 years ago

Our project is very complex and getting it running on OpenJDK would likely be very costly...

frol commented 8 years ago

@tpischke Then go and fork it. Just don't copy those broken manuals, please.

tpischke commented 8 years ago

I just copied the Dockerfiles from alpine-glibc and alpine-oraclejdk8 and built the images locally myself. Works beautifully. I'll discuss migration to OpenJDK with the team, but that's not going to happen in the near term. Testing alone will be a major effort if we migrate. For now I have a brilliant working solution, thanks to you guys. Alpine Docker Images are extremely compelling.

jirutka commented 8 years ago

Can the java version be specified? We test and recommend specific java versions to our customers.

No, only major version (there’s package openjdk7 and openjdk8). However, you can copy the openjdk8 abuild, adjust version (and patches if needed) and build it yourself. It’s quite easy and you’ll have it fully under your control.

'unofficial' external dependencies are forbidden by the project lead.

Then why are you trying to use that glibc package on Alpine? This is unofficial hack that is not supported by Alpine community. The only officially supported JRE/JDK are the mentioned openjdk packages built against musl libc.

Our project is very complex and getting it running on OpenJDK would likely be very costly...

Then you’re probably doing it wrong… Oracle JDK is just branded distribution of OpenJDK, the code base is nearly identical. That said, exceptions may exist, mainly in case of graphic applications.

If you really need OracleJDK, then use some glibc-based distribution, not Alpine. Adding glibc to Alpine is not a stable production-quality solution.

frol commented 8 years ago

@jirutka I also suggest to use OpenJDK wherever possible, but 60k pulls of my OracleJDK image suggest that it is stable enough, and I have been using it in production for quite a bit. Though, it depends on how you define the "production-quality" because Docker itself might be considered as not a production ready solution.

tpischke commented 8 years ago

We need to use Oracle Java, and it would sure be nice to use alpine linux. The fact that the official docker images are moving to alpine also plays a role in the decision. I hope alpine considers officially supporting oracle java in the future. For many java developers, openjdk is no alternative.

jirutka commented 8 years ago

…Docker itself might be considered as not a production ready solution.

Well, that’s very true! :)

I hope alpine considers officially supporting oracle java in the future.

Once again. Oracle JDK is a proprietary product, they don’t provide source-code of all their modifications to OpenJDK and build system, just binaries. These binaries are build against glibc (GNU C Library). Alpine Linux doesn’t use glibc, it’s based on (much better) musl libc.

Glibc and musl libc are (partially) incompatible (mainly because glibc doesn’t comply with POSIX standards). Therefore software built against glibc may not work on musl libc without recompiling. This is the case of Oracle JDK. Because it’s a proprietary product, we can’t recompile it and there’s nothing we can do about it!

libc is a very base system library, it’s not yet another library you can simply install along with others. Adding support for glibc would basically mean supporting another platform. The cost of this is too high. Also it doesn’t make much sense; Alpine with glibc would not be Alpine anymore! Alpine’s “motto” is: small, simply and secure. You can’t get this with glibc.

Ask Oracle for musl support, they have the key, not Alpine.

ralph-tice commented 8 years ago

Just as musl and glibc 'should' be interchangeable, the reality is that OpenJDK and Oracle JDK also 'should' be interchangeable. They're not, and it's irresponsible to ship hacks that enable glibc in a broken way on top of a musl-based system.

jirutka commented 8 years ago

Just as musl and glibc 'should' be interchangeable, the reality is that OpenJDK and Oracle JDK also 'should' be interchangeable.

This is very different situation. glibc and musl libc are different software, they both implements POSIX standards, but the code base is totally different. Oracle JDK is just a branded distribution of OpenJDK, the source code base is the same. Also you can easily install more JDKs side by side on one system, but not two libc.

ralph-tice commented 8 years ago

You can't safely and stably install an Oracle JDK on a system with musl libc and it needs to be prominently admitted that such is the case instead of pushing these hacks forward.

You're also wrong about OracleJDK vs OpenJDK, there are significant differences and they do impact performance and stability. They can exist side by side with glibc provided to them, but the whole point of this exercise is that OracleJDK isn't compiled against musl libc.

zaunerc commented 8 years ago

I have contacted the Oracle support and I got the following statements regarding libmusl and the JRE / JDK:

The Oracle Java product organization maintains a limited number of "standard" configurations for Java and there is no plan to build it with the libmusl library. When customers request Java for other configurations, the Oracle Java product organization - Java Engineering Services (JES) - can create, certify and maintain custom version of Java for alternative O/S, special libraries, embedded architectures, older code bases, etc.

A typical engagement with JES would be: JES proposes a fixed-price engagement to do a "port" which is to deliver a certified version of Java on a non-standard platform. JES could also offer 12-months of Maintenance (renewable each year) to fix bugs and give updates.

ncopa commented 8 years ago

So basically, if you need OracleJDK, you'll have to use one of the "standard" configurations for Java (eg use windows or oracle linux). If you need something else you'll have to hire JES.

leodutra commented 8 years ago

"Most cross-compatible platform", they say...

The only exit would be a thin glibc facade bound to musl. And maybe this would be a kick for musl usage too.

Now we just need social engineering to convince a crazy guy for doing this.

Denusdv commented 6 years ago

We have a new glibc package if anyone would like to test this out. You can grab the package at https://circle-artifacts.com/gh/andyshinn/alpine-pkg-glibc/6/artifacts/0/home/ubuntu/alpine-pkg-glibc/packages/x86_64/glibc-2.21-r2.apk and install with apk add --allow-untrusted glibc-2.21-r2.apk. This should allow Oracle Java 8 and other glibc x86_64 native binaries to run on Alpine.

Do you provide the version compatible for ARM64 arch?

jtlz2 commented 5 years ago

@Denusdv "no such project" at that link? :\

sgerrand commented 5 years ago

Hello, I took over maintenance of the glibc package from Andy. There are more recent versions available for download and installation at https://github.com/sgerrand/alpine-pkg-glibc/releases. I suggest you try there.

realtimetodie commented 3 years ago

https://bugs.openjdk.java.net/browse/JDK-8229469