diff --git a/crdt.cabal b/crdt.cabal
--- a/crdt.cabal
+++ b/crdt.cabal
@@ -1,5 +1,5 @@
 name: crdt
-version: 9.1
+version: 9.2
           -- ^ ComVer
 category: Distributed Systems
 copyright:
@@ -20,10 +20,6 @@
     type: git
     location: https://github.com/cblp/crdt.git
 
-flag Cm
-    description: Include commutative types
-    default: True
-
 library
     hs-source-dirs: lib
     build-depends:  base >= 4.8 && < 4.11
@@ -33,11 +29,12 @@
                   , Diff
                   , hashable
                   , mtl
-                  , network-info
                   , safe
                   , stm
                   , time
                   , vector
+    -- if !impl(eta)
+    --     build-depends:  network-info
     exposed-modules:  CRDT.Cv
                       CRDT.Cv.GCounter
                       CRDT.Cv.GSet
@@ -52,14 +49,14 @@
                       CRDT.LWW
                       Data.MultiMap
                       Data.Semilattice
-    if flag(Cm)
-        cpp-options: -DENABLE_CM=1
+    if impl(ghc >= 8)
         exposed-modules:  CRDT.Cm
                           CRDT.Cm.Counter
                           CRDT.Cm.GSet
                           CRDT.Cm.ORSet
                           CRDT.Cm.RGA
                           CRDT.Cm.TwoPSet
+    other-modules: MacAddress
     default-language: Haskell2010
 
     if impl(ghc >= 8)
diff --git a/lib/CRDT/LWW.hs b/lib/CRDT/LWW.hs
--- a/lib/CRDT/LWW.hs
+++ b/lib/CRDT/LWW.hs
@@ -2,9 +2,9 @@
 {-# LANGUAGE NamedFieldPuns #-}
 {-# LANGUAGE TypeFamilies #-}
 
-#if ENABLE_CM
+#if __GLASGOW_HASKELL__ >= 800
 {-# LANGUAGE LambdaCase #-}
-#endif /* ENABLE_CM */
+#endif /* __GLASGOW_HASKELL__ >= 800 */
 
 module CRDT.LWW
     ( LWW (..)
@@ -20,9 +20,9 @@
 
 import           Data.Semilattice (Semilattice)
 
-#if ENABLE_CM
+#if __GLASGOW_HASKELL__ >= 800
 import           CRDT.Cm (CausalOrd (..), CmRDT (..))
-#endif /* ENABLE_CM */
+#endif /* __GLASGOW_HASKELL__ >= 800 */
 
 import           CRDT.LamportClock (Clock, LamportTime (LamportTime), advance,
                                     getTime)
@@ -72,7 +72,7 @@
 --------------------------------------------------------------------------------
 -- CmRDT -----------------------------------------------------------------------
 
-#if ENABLE_CM
+#if __GLASGOW_HASKELL__ >= 800
 
 instance CausalOrd (LWW a) where
     precedes _ _ = False
@@ -91,7 +91,7 @@
         Just payload -> op <> payload
         Nothing      -> op
 
-#endif /* ENABLE_CM */
+#endif /* __GLASGOW_HASKELL__ >= 800 */
 
 advanceFromLWW :: Clock m => LWW a -> m ()
 advanceFromLWW LWW{time = LamportTime time _} = advance time
diff --git a/lib/CRDT/LamportClock.hs b/lib/CRDT/LamportClock.hs
--- a/lib/CRDT/LamportClock.hs
+++ b/lib/CRDT/LamportClock.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE DeriveFunctor #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE NamedFieldPuns #-}
@@ -15,6 +16,7 @@
     , runLamportClock
     -- * Helpers
     , getRealLocalTime
+    , getMacAddress
     ) where
 
 import           Control.Concurrent.STM (TVar, atomically, modifyTVar',
@@ -23,14 +25,12 @@
 import           Control.Monad.Reader (ReaderT, ask, runReaderT)
 import           Control.Monad.State.Strict (StateT)
 import           Control.Monad.Trans (lift)
-import           Data.Binary (decode)
-import qualified Data.ByteString.Lazy as BSL
 import           Data.Time.Clock.POSIX (getPOSIXTime)
 import           Data.Word (Word64)
-import           Network.Info (MAC (MAC), getNetworkInterfaces, mac)
 import           Numeric.Natural (Natural)
-import           Safe (headDef)
 
+import           MacAddress (getMacAddress)
+
 -- | Unix time in 10^{-7} seconds (100 ns), as in RFC 4122 and Swarm RON.
 type LocalTime = Natural
 
@@ -50,20 +50,6 @@
 getRealLocalTime :: IO LocalTime
 getRealLocalTime = round . (* 10000000) <$> getPOSIXTime
 
-getPidByMac :: IO Pid
-getPidByMac = Pid . decodeMac <$> getMac
-  where
-    getMac :: IO MAC
-    getMac =
-        headDef (error "Can't get any non-zero MAC address of this machine")
-            .   filter (/= minBound)
-            .   map mac
-            <$> getNetworkInterfaces
-
-    decodeMac :: MAC -> Word64
-    decodeMac (MAC b5 b4 b3 b2 b1 b0) =
-        decode $ BSL.pack [0, 0, b5, b4, b3, b2, b1, b0]
-
 class Process m => Clock m where
     -- | Get sequential timestamps.
     --
@@ -91,7 +77,7 @@
 runLamportClock var (LamportClock action) = runReaderT action var
 
 instance Process LamportClock where
-    getPid = liftIO getPidByMac
+    getPid = Pid <$> liftIO getMacAddress
 
 instance Clock LamportClock where
     advance time = LamportClock $ do
diff --git a/lib/MacAddress.hs b/lib/MacAddress.hs
new file mode 100644
--- /dev/null
+++ b/lib/MacAddress.hs
@@ -0,0 +1,65 @@
+{-# LANGUAGE CPP #-}
+
+module MacAddress where
+
+import           Data.Binary (decode)
+import qualified Data.ByteString.Lazy as BSL
+import           Safe (headDef)
+
+#ifdef ETA_VERSION
+
+import           Java
+
+import           Data.Maybe (catMaybes)
+import           Data.Traversable (for)
+import           Data.Word (Word64, Word8)
+
+#else /* ETA_VERSION */
+
+import           Data.Word (Word64)
+import           Network.Info (MAC (MAC), getNetworkInterfaces, mac)
+
+#endif /* ETA_VERSION */
+
+getMacAddress :: IO Word64
+
+#ifdef ETA_VERSION
+
+getMacAddress = java $ do
+    interfaces <- fromJava <$> getNetworkInterfaces
+    macs <- for interfaces (<.> getHardwareAddress)
+    let macBytes =
+            headDef (error "Can't get any non-zero MAC address of this machine")
+            $ catMaybes macs
+    let mac = foldBytes $ fromJava macBytes
+    pure mac
+
+data NetworkInterface = NetworkInterface @java.net.NetworkInterface
+    deriving Class
+
+foreign import java unsafe
+    "@static java.net.NetworkInterface.getNetworkInterfaces"
+    getNetworkInterfaces :: Java a (Enumeration NetworkInterface)
+
+foreign import java unsafe
+    getHardwareAddress :: Java NetworkInterface (Maybe JByteArray)
+
+foldBytes :: [Word8] -> Word64
+foldBytes bytes = decode . BSL.pack $ replicate (8 - length bytes) 0 ++ bytes
+
+#else /* ETA_VERSION */
+
+getMacAddress = decodeMac <$> getMac
+
+getMac :: IO MAC
+getMac =
+    headDef (error "Can't get any non-zero MAC address of this machine")
+    .   filter (/= minBound)
+    .   map mac
+    <$> getNetworkInterfaces
+
+decodeMac :: MAC -> Word64
+decodeMac (MAC b5 b4 b3 b2 b1 b0) =
+    decode $ BSL.pack [0, 0, b5, b4, b3, b2, b1, b0]
+
+#endif /* ETA_VERSION */
