From 00805d72728f534417549db48efbd15f7c206750 Mon Sep 17 00:00:00 2001 From: Cam Saul <cammsaul@gmail.com> Date: Wed, 16 May 2018 13:48:12 -0700 Subject: [PATCH] Drop support for Java 7 :wave: --- bin/docker/run_metabase.sh | 2 - circle.yml | 2 +- .../running-the-metabase-jar-file.md | 4 +- docs/operations-guide/start.md | 12 +--- docs/troubleshooting-guide/running.md | 22 ------ frontend/test/__runner__/backend.js | 5 +- project.clj | 5 +- src/metabase/core.clj | 68 +++++++------------ src/metabase/plugins.clj | 12 ++-- 9 files changed, 37 insertions(+), 95 deletions(-) diff --git a/bin/docker/run_metabase.sh b/bin/docker/run_metabase.sh index 66f487756e7..915c463a4d5 100755 --- a/bin/docker/run_metabase.sh +++ b/bin/docker/run_metabase.sh @@ -113,8 +113,6 @@ chown metabase:metabase $new_db_dir $new_db_dir/* 2>/dev/null # all that fussin JAVA_OPTS="${JAVA_OPTS} -XX:+IgnoreUnrecognizedVMOptions" JAVA_OPTS="${JAVA_OPTS} -Dfile.encoding=UTF-8" JAVA_OPTS="${JAVA_OPTS} -Dlogfile.path=target/log" -JAVA_OPTS="${JAVA_OPTS} -XX:+CMSClassUnloadingEnabled" # These two needed for Java 7 to GC dynamically generated classes -JAVA_OPTS="${JAVA_OPTS} -XX:+UseConcMarkSweepGC" JAVA_OPTS="${JAVA_OPTS} -server" JAVA_OPTS="${JAVA_OPTS} --add-modules=java.xml.bind" # needed for Java 9 (Oracle VM only) because java.xml.bind is no longer on SE classpath by default since it's EE diff --git a/circle.yml b/circle.yml index 45657b85b5a..07a4df17fb0 100644 --- a/circle.yml +++ b/circle.yml @@ -3,7 +3,7 @@ machine: America/Los_Angeles java: version: - openjdk7 + openjdk8 node: version: 8.9.0 services: diff --git a/docs/operations-guide/running-the-metabase-jar-file.md b/docs/operations-guide/running-the-metabase-jar-file.md index 005d7b9d0c0..6ddbc7a8f6a 100644 --- a/docs/operations-guide/running-the-metabase-jar-file.md +++ b/docs/operations-guide/running-the-metabase-jar-file.md @@ -1,6 +1,6 @@ # Running the Metabase Jar File -To run the Metabase jar file you need to have Java installed on your system. Currently Metabase requires Java 7 or higher and will work on either the OpenJDK or Oracle JDK. Note that the Metabase team prefers to stick with open source solutions where possible, so we use the OpenJDK for our Metabase instances. +To run the Metabase jar file you need to have Java installed on your system. Currently Metabase requires Java 8 or higher and will work on either the OpenJDK or Oracle JDK. ### Download Metabase @@ -21,7 +21,7 @@ You should see output such as: If you did not see the output above and instead saw either an error or your Java version is less than 1.7, then you need to install the Java Runtime. -[OpenJDK Downloads](http://openjdk.java.net/install/) +[OpenJDK Downloads](http://openjdk.java.net/install/) [Oracle's Java Downloads](http://www.oracle.com/technetwork/java/javase/downloads/index.html) diff --git a/docs/operations-guide/start.md b/docs/operations-guide/start.md index 0f82f5c3236..baf39ceb11b 100644 --- a/docs/operations-guide/start.md +++ b/docs/operations-guide/start.md @@ -335,15 +335,7 @@ Diagnosing performance related issues can be a challenge. Luckily the JVM ships # Java Versions -Metabase will run on Java version 7 or greater, but Java 8 is the easiest and most common chioce. Java 7 was End of Life'd by Oracle in April of 2015 and as such, *Metabase support for Java 7 has been deprecated*. Users are encouraged to upgrade to Java 8 as we will drop support for Java 7 in a future release. For more information on installing/upgrading a Windows or macOS system, see the [Oracle installation instructions](https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html). Linux users likely find OpenJDK easier to install/upgrade, more information is available on [the OpenJDK install page](http://openjdk.java.net/install/). - -## Running on Java 7 - -Running Metabase on Java version 7 requires additional arguments to the Java invocation: - - java -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m -jar metabase.jar - -Note that these extra arguments are not required on Java 8. *Support for Java 7 has been deprecated and users are encouraged to upgrade*. +Metabase will run on Java version 8 or greater; Java 8 is the easiest and most common choice. ## Running on Java 8 @@ -351,7 +343,7 @@ Running on Java 8 is the easiest path to running Metabase. There are no addition java -jar metabase.jar -## Running on Java 9 +## Running on Java 9 or Newer To use Metabase on Java 9 with Oracle, Vertica, SparkSQL, or other drivers that require external dependencies, you'll need to tweak the way you launch Metabase. diff --git a/docs/troubleshooting-guide/running.md b/docs/troubleshooting-guide/running.md index d080ff377fb..91164779341 100644 --- a/docs/troubleshooting-guide/running.md +++ b/docs/troubleshooting-guide/running.md @@ -1,28 +1,6 @@ ## Specific Problems: - -### Metabase fails to start due to PermGen OutOfMemoryErrors - -On Java 7, Metabase may fail to launch with a message like - - java.lang.OutOfMemoryError: PermGen space - -or one like - - Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler - -If this happens, setting a few JVM options should fix your issue: - - java -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m -jar metabase.jar - -You can also pass JVM arguments by setting the environment variable `JAVA_TOOL_OPTIONS`, e.g. - - JAVA_TOOL_OPTIONS='-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:MaxPermSize=256m' - -Alternatively, you can upgrade to Java 8 instead, which will fix the issue as well. - - ### Metabase fails to start due to Heap Space OutOfMemoryErrors Normally, the JVM can figure out how much RAM is available on the system and automatically set a sensible upper bound for heap memory usage. On certain shared hosting diff --git a/frontend/test/__runner__/backend.js b/frontend/test/__runner__/backend.js index 5e58c2c4bcc..5df9cfb1608 100644 --- a/frontend/test/__runner__/backend.js +++ b/frontend/test/__runner__/backend.js @@ -48,13 +48,10 @@ export const BackendResource = createSharedResource("BackendResource", { server.process = spawn( "java", [ - "-XX:+IgnoreUnrecognizedVMOptions", // ignore options not recognized by this Java version (e.g. Java 7/8 should ignore Java 9 options) + "-XX:+IgnoreUnrecognizedVMOptions", // ignore options not recognized by this Java version (e.g. Java 8 should ignore Java 9 options) "-Dh2.bindAddress=localhost", // fix H2 randomly not working (?) "-Xmx2g", // Hard limit of 2GB size for the heap since Circle is dumb and the JVM tends to go over the limit otherwise - "-XX:MaxPermSize=256m", // (Java 7) Give JVM a little more headroom in the PermGen space. Cloure makes lots of one-off classes! "-Xverify:none", // Skip bytecode verification for the JAR so it launches faster - "-XX:+CMSClassUnloadingEnabled", // (Java 7) Allow GC to collect classes. Clojure makes lots of one-off dynamic classes - "-XX:+UseConcMarkSweepGC", // (Java 7) Use Concurrent Mark & Sweep GC which allows classes to be GC'ed "-Djava.awt.headless=true", // when running on macOS prevent little Java icon from popping up in Dock "--add-modules=java.xml.bind", // Tell Java 9 we want to use java.xml stuff "-jar", diff --git a/project.clj b/project.clj index d9a5a61ff8c..7bafa957789 100644 --- a/project.clj +++ b/project.clj @@ -114,13 +114,10 @@ :manifest {"Liquibase-Package" "liquibase.change,liquibase.changelog,liquibase.database,liquibase.parser,liquibase.precondition,liquibase.datatype,liquibase.serializer,liquibase.sqlgenerator,liquibase.executor,liquibase.snapshot,liquibase.logging,liquibase.diff,liquibase.structure,liquibase.structurecompare,liquibase.lockservice,liquibase.sdk,liquibase.ext"} :target-path "target/%s" :jvm-opts ["-XX:+IgnoreUnrecognizedVMOptions" ; ignore things not recognized for our Java version instead of refusing to start - "-XX:MaxPermSize=256m" ; give the JVM a little more PermGen space to avoid PermGen OutOfMemoryErrors "-Xverify:none" ; disable bytecode verification when running in dev so it starts slightly faster - "-XX:+CMSClassUnloadingEnabled" ; let Clojure's dynamically generated temporary classes be GC'ed from PermGen - "-XX:+UseConcMarkSweepGC" ; Concurrent Mark Sweep GC needs to be used for Class Unloading (above) "--add-modules=java.xml.bind" ; tell Java 9 (Oracle VM only) to add java.xml.bind to classpath. No longer on it by default. See https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception-in-j "-Djava.awt.headless=true"] ; prevent Java icon from randomly popping up in dock when running `lein ring server` - :javac-options ["-target" "1.7", "-source" "1.7"] + :javac-options ["-target" "1.8", "-source" "1.8"] :uberjar-name "metabase.jar" :ring {:handler metabase.core/app :init metabase.core/init! diff --git a/src/metabase/core.clj b/src/metabase/core.clj index 1023881165f..f25ee326bdc 100644 --- a/src/metabase/core.clj +++ b/src/metabase/core.clj @@ -23,7 +23,7 @@ [setting :as setting] [user :refer [User]]] [metabase.util.i18n :refer [set-locale]] - [puppetlabs.i18n.core :refer [locale-negotiator]] + [puppetlabs.i18n.core :refer [locale-negotiator trs]] [ring.adapter.jetty :as ring-jetty] [ring.middleware [cookies :refer [wrap-cookies]] @@ -106,9 +106,7 @@ wrap-gzip)) ; GZIP response if client can handle it -;;; ## ---------------------------------------- LIFECYCLE ---------------------------------------- - - +;;; --------------------------------------------------- Lifecycle ---------------------------------------------------- (defn- -init-create-setup-token "Create and set a new setup token and log it." @@ -120,21 +118,24 @@ (or hostname "localhost") (when-not (= 80 port) (str ":" port)) "/setup/")] - (log/info (u/format-color 'green "Please use the following url to setup your Metabase installation:\n\n%s\n\n" - setup-url)))) + (log/info (u/format-color 'green + (str (trs "Please use the following URL to setup your Metabase installation:") + "\n\n" + setup-url + "\n\n"))))) (defn- destroy! "General application shutdown function which should be called once at application shuddown." [] - (log/info "Metabase Shutting Down ...") + (log/info (trs "Metabase Shutting Down ...")) (task/stop-scheduler!) - (log/info "Metabase Shutdown COMPLETE")) + (log/info (trs "Metabase Shutdown COMPLETE"))) (defn init! "General application initialization function which should be run once at application startup." [] - (log/info (format "Starting Metabase version %s ..." config/mb-version-string)) - (log/info (format "System timezone is '%s' ..." (System/getProperty "user.timezone"))) + (log/info (trs (format "Starting Metabase version {0} ..." config/mb-version-string))) + (log/info (trs (format "System timezone is ''{0}'' ..." (System/getProperty "user.timezone")))) (init-status/set-progress! 0.1) ;; First of all, lets register a shutdown hook that will tidy things up for us on app exit @@ -150,7 +151,7 @@ (init-status/set-progress! 0.4) ;; startup database. validates connection & runs any necessary migrations - (log/info "Setting up and migrating Metabase DB. Please sit tight, this may take a minute...") + (log/info (trs "Setting up and migrating Metabase DB. Please sit tight, this may take a minute...")) (mdb/setup-db! :auto-migrate (config/config-bool :mb-db-automigrate)) (init-status/set-progress! 0.5) @@ -167,7 +168,7 @@ (init-status/set-progress! 0.8) (when new-install? - (log/info "Looks like this is a new installation ... preparing setup wizard") + (log/info (trs "Looks like this is a new installation ... preparing setup wizard")) ;; create setup token (-init-create-setup-token) ;; publish install event @@ -187,7 +188,7 @@ (set-locale (setting/get :site-locale)) (init-status/set-complete!) - (log/info "Metabase Initialization COMPLETE")) + (log/info (trs "Metabase Initialization COMPLETE"))) ;;; ## ---------------------------------------- Jetty (Web) Server ---------------------------------------- @@ -210,8 +211,10 @@ (config/config-str :mb-jetty-daemon) (assoc :daemon? (config/config-bool :mb-jetty-daemon)) (config/config-str :mb-jetty-ssl) (-> (assoc :ssl? true) (merge jetty-ssl-config)))] - (log/info "Launching Embedded Jetty Webserver with config:\n" (with-out-str (pprint/pprint (m/filter-keys #(not (re-matches #".*password.*" (str %))) - jetty-config)))) + (log/info (trs "Launching Embedded Jetty Webserver with config:") + "\n" + (with-out-str (pprint/pprint (m/filter-keys #(not (re-matches #".*password.*" (str %))) + jetty-config)))) ;; NOTE: we always start jetty w/ join=false so we can start the server first then do init in the background (->> (ring-jetty/run-jetty app (assoc jetty-config :join? false)) (reset! jetty-instance))))) @@ -220,38 +223,16 @@ "Stop the embedded Jetty web server." [] (when @jetty-instance - (log/info "Shutting Down Embedded Jetty Webserver") + (log/info (trs "Shutting Down Embedded Jetty Webserver")) (.stop ^Server @jetty-instance) (reset! jetty-instance nil))) -(defn- wrap-with-asterisk [strings-to-wrap] - ;; Adding 4 extra asterisks so that we account for the leading asterisk and space, and add two more after the end of the sentence - (let [string-length (+ 4 (apply max (map count strings-to-wrap)))] - (str (apply str (repeat string-length \* )) - "\n" - "*\n" - (apply str (map #(str "* " % "\n") strings-to-wrap)) - "*\n" - (apply str (repeat string-length \* ))))) - -(defn- check-jdk-version [] - (let [java-spec-version (System/getProperty "java.specification.version")] - ;; Note for java 7, this is 1.7, but newer versions drop the 1. Java 9 just returns "9" here. - (when (= "1.7" java-spec-version) - (let [java-version (System/getProperty "java.version") - deprecation-messages [(str "DEPRECATION WARNING: You are currently running JDK '" java-version "'. " - "Support for Java 7 has been deprecated and will be dropped from a future release.") - (str "See the operation guide for more information: https://metabase.com/docs/latest/operations-guide/start.html.")]] - (binding [*out* *err*] - (println (wrap-with-asterisk deprecation-messages)) - (log/warn deprecation-messages)))))) - -;;; ## ---------------------------------------- Normal Start ---------------------------------------- + +;;; -------------------------------------------------- Normal Start -------------------------------------------------- (defn- start-normally [] - (log/info "Starting Metabase in STANDALONE mode") + (log/info (trs "Starting Metabase in STANDALONE mode")) (try - (check-jdk-version) ;; launch embedded webserver async (start-jetty!) ;; run our initialization process @@ -260,8 +241,7 @@ (when (config/config-bool :mb-jetty-join) (.join ^Server @jetty-instance)) (catch Throwable e - (.printStackTrace e) - (log/error "Metabase Initialization FAILED: " (.getMessage e)) + (log/error e (trs "Metabase Initialization FAILED")) (System/exit 1)))) (defn- run-cmd [cmd args] @@ -269,7 +249,7 @@ ((resolve 'metabase.cmd/run-cmd) cmd args)) -;;; ---------------------------------------- App Entry Point ---------------------------------------- +;;; ------------------------------------------------ App Entry Point ------------------------------------------------- (defn -main "Launch Metabase in standalone mode." diff --git a/src/metabase/plugins.clj b/src/metabase/plugins.clj index 3b5b4733c6a..3ce3d4e67f5 100644 --- a/src/metabase/plugins.clj +++ b/src/metabase/plugins.clj @@ -1,7 +1,7 @@ (ns metabase.plugins "The Metabase 'plugins' system automatically adds JARs in the `./plugins/` directory (parallel to `metabase.jar`) to - the classpath at runtime. This works great on Java 7 and 8, but never really worked properly on Java 9; as of 0.29.4 - we're planning on telling people to just add extra external dependencies with `-cp` when using Java 9." + the classpath at runtime. This works great on Java 8, but never really worked properly on Java 9; as of 0.29.4 we're + planning on telling people to just add extra external dependencies with `-cp` when using Java 9." (:require [clojure.java.io :as io] [clojure.tools.logging :as log] [dynapath.util :as dynapath] @@ -11,7 +11,7 @@ [puppetlabs.i18n.core :refer [trs]])) ;;; +----------------------------------------------------------------------------------------------------------------+ -;;; | Java 7 + 8 | +;;; | Java 8 | ;;; +----------------------------------------------------------------------------------------------------------------+ (defn- plugins-dir @@ -48,7 +48,7 @@ ;;; +----------------------------------------------------------------------------------------------------------------+ -;;; | Java 9 | +;;; | Java 9+ | ;;; +----------------------------------------------------------------------------------------------------------------+ (defn- show-java-9-message @@ -71,8 +71,8 @@ ;;; +----------------------------------------------------------------------------------------------------------------+ (defn load-plugins! - "Dynamically add JARs if we're running on Java 7 or 8. For Java 9, where this doesn't work, just display a nice - message instead." + "Dynamically add JARs if we're running on Java 8. For Java 9+, where this doesn't work, just display a nice message + instead." [] (if (u/is-java-9-or-higher?) (show-java-9-message) -- GitLab