Closed aytekinar closed 5 years ago
I also experience this under windows when I use the jar. @tobiasdiez any idea?
With modularized Java 11 applications, the jar
file does no longer work / is no longer the supported distribution mechanism. Instead, you should create a runtime image using gradle jlink
and then run it via java -m org.jabref/org.jabref.JabRefLauncher
.
Thanks to both of you for your fast responses.
@tobiasdiez, I can confirm that running
gradle jlink
gradle run
compiles and runs JabRef without any problems. However, I cannot make it work with
gradle jlink
java -m org.jabref/org.jabref.JabRefLauncher
when working under the source tree. The command gives the following error this time:
Error occurred during initialization of boot layer
java.lang.module.FindException: Module org.jabref not found
When I run tree -L 2 build
, I get the following:
build
├── classes
│ └── java
├── generated
│ └── sources
├── image
│ ├── bin
│ ├── conf
│ ├── legal
│ ├── lib
│ └── release
├── jlinkbase
│ ├── delegating
│ ├── jlinkjars
│ ├── mergedjars
│ ├── nonmodjars
│ ├── tmpjars
│ ├── tmpmerged
│ └── tmpmodinfo
├── libs
│ └── JabRef-5.0-dev.jar
├── resources
│ └── main
└── tmp
├── compileJava
└── jar
I am assuming that
build
to a specific path under my user space, or--module-path
switch to java
when running the module.I would appreciate if you provided a minimal working example. Then, I can write a PKGBUILD
file for my system or update the paths under my user space accordingly.
Final comment...
As of 18cf80f95d, the following PKGBUILD
file works for Arch Linux:
pkgname=jabref
pkgver=r13251.18cf80f95d
pkgrel=1
pkgdesc='Graphical Java application for managing BibTeX and biblatex (.bib) databases.'
arch=('x86_64')
url='https://www.jabref.org'
license=('MIT')
source=("git+https://github.com/JabRef/jabref")
sha256sums=('SKIP')
makedepends=('gendesk' 'gradle' 'jdk-openjdk')
provides=('jabref')
conflicts=('jabref')
prepare() {
gendesk ../PKGBUILD
sed 's|Exec=jabref|Exec=/opt/jabref/image/bin/JabRefMain|g' --in-place jabref.desktop
}
pkgver() {
cd "${pkgname}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
build() {
cd "${srcdir}/${pkgname}"
git submodule update --init
gradle jlink
}
package() {
cd "${srcdir}"
install -d "${pkgdir}/opt"
cp -R "${pkgname}/build" "${pkgdir}/opt/jabref"
install -D jabref.desktop "${pkgdir}/usr/share/applications/jabref.desktop"
install -D jabref.png "${pkgdir}/usr/share/pixmaps/jabref.desktop"
}
Basically, after gradle jlink
ing, moving everything under build
to /opt/jabref
and running /opt/jabref/image/bin/JabRefMain
from a desktop file works. The only problem, though, is the installed package size: 705.38 MiB. I would appreciate if there were a way to make the package smaller (i.e., perhaps installing things the "jar" way).
Thanks for the update. That size is indeed huge, I found out that this is somehow a linux issue with jlink and that there is a workaround for reducing the size:
$ strip -p --strip-unneeded lib/server/libjvm.so
https://github.com/docker-library/openjdk/issues/217#issuecomment-436275472
@aytekinar It should suffice to use what is inside of build/image
after gradle jlink
. The bin
folder should contain a luncher script (JabRefMain.bat
on Windows).
@Siedlerchr I will try to do the manual stripping. However, Arch Linux also does stripping when packaging binaries.
@tobiasdiez I would appreciate if you could write an MWE for that. I can get rid of the bin
directory, but I do not know how to launch JabRef in this new way. See my comment above.
I have no linux at hand, so I cannot give more details sorry. On Windows, the build/image/bin
folder contains JabRefMain.bat
and if I click on this file JabRef starts successfully. I would guess that the same folder contains a luncher (JabRefMain.sh
?) also on linux. If not can you please paste the content of that folder here. Thanks
Update 1. Stripping the image manually as suggested by @Siedlerchr, as of a357bbd598, still results in 705.38 MiB.
Update 2. image/bin
contains the following:
~> tree /opt/jabref/image/bin/
/opt/jabref/image/bin/
├── JabRefMain
├── JabRefMain.bat
├── jar
├── jarsigner
├── java
├── javac
├── javadoc
├── javap
├── jdeprscan
├── jdeps
├── jfr
├── jimage
├── jlink
├── jmod
├── jrunscript
├── keytool
├── rmid
├── rmiregistry
└── serialver
and its size is
~> du --summarize --human-readable /opt/jabref/image/bin/
284K /opt/jabref/image/bin/
In fact, JabRefMain
is a shell script, as you have guessed @tobiasdiez, with the following content:
#!/bin/sh
DIR="${0%/*}"
"$DIR/java" -p "$DIR/../app" -m org.jabref/org.jabref.JabRefLauncher "$@"
which uses the java
binary under the same directory to point to the app
path in the directory above. Weird enough, find /opt/jabref/ -name app
gives nothing (i.e., there is no such directory or file inside the package).
In short,
strip
ping the libraries manually did not help because I assume that Arch Linux's package manager (pacman
) strips the binaries by default if not instructed otherwise,image/bin
directory is not the bottleneck (i.e., it has 284K size).That said, I think this issue is not open anymore. Anybody with a problem on Arch Linux can see the solution you have suggested and either use my PKGBUILD
suggestion above or find their way accordingly.
Edit. For your reference, the package size has the following distribution among the package's modules/directories:
~> du --summarize --human-readable /opt/jabref/*
11M /opt/jabref/classes
20K /opt/jabref/generated
161M /opt/jabref/image
581M /opt/jabref/jlinkbase
14M /opt/jabref/libs
60M /opt/jabref/resources
16K /opt/jabref/tmp
~> du --summarize --human-readable /opt/jabref/image/*
284K /opt/jabref/image/bin
120K /opt/jabref/image/conf
404K /opt/jabref/image/legal
160M /opt/jabref/image/lib
4,0K /opt/jabref/image/release
~> du --summarize --human-readable /opt/jabref/jlinkbase/*
292K /opt/jabref/jlinkbase/delegating
104M /opt/jabref/jlinkbase/jlinkjars
296M /opt/jabref/jlinkbase/mergedjars
96M /opt/jabref/jlinkbase/nonmodjars
580K /opt/jabref/jlinkbase/tmpjars
87M /opt/jabref/jlinkbase/tmpmerged
16K /opt/jabref/jlinkbase/tmpmodinfo
There is already one maintaining an Arch repo for jabref: (I think it's @j0hannes ) so I guess your experiences might help. https://aur.archlinux.org/packages/jabref-latest/
It would be nice if someone of you could then update the installation instructions page in the help http://help.jabref.org/en/Installation#installation-commands (Just click "Edit this page") at the bottom
There is already one maintaining an Arch repo for jabref: (I think it's @j0hannes ) so I guess your experiences might help. https://aur.archlinux.org/packages/jabref-latest/
I am aware of that package. Unfortunately, I am right now writing a paper and I cannot open my bibliography files (well, yes, I can open them in text editors, but you know...). If you check the latest comment, @j0hannes is still testing Java 11 issues. In the meantime, I needed to write mine.
It would be nice if someone of you could then update the installation instructions page in the help http://help.jabref.org/en/Installation#installation-commands (Just click "Edit this page") at the bottom
There is no need to update Arch and Manjaro part. Because I am not pushing my PKGBUILD
to AUR, @j0hannes's solution is still the only option (no competing packages). However, should @j0hannes add me to the AUR repo, I would be more than happy to push my suggestion. Otherwise, they can obtain mine easily. By the way, the sed
line will not be needed once this goes upstream.
Edit. In fact, there might be a small update later to the statement:
Both packages install precompiled jar files and add a command and a .desktop file to the OS.
if @j0hannes decides to borrow my solution (i.e., building from source).
Hi,
There is already one maintaining an Arch repo for jabref: (I think it's @j0hannes ) so I guess your experiences might help. https://aur.archlinux.org/packages/jabref-latest/
I am aware of that package. Unfortunately, I am right now writing a paper and I cannot open my bibliography files (well, yes, I can open them in text editors, but you know...). If you check the latest comment, @j0hannes is still testing Java 11 issues. In the meantime, I needed to write mine.
I released a new PKGBUILD the day after that comment. Since then, it's working fine for me.
It would be nice if someone of you could then update the installation instructions page in the help http://help.jabref.org/en/Installation#installation-commands (Just click "Edit this page") at the bottom
There is no need to update Arch and Manjaro part. Because I am not pushing my
PKGBUILD
to AUR, @j0hannes's solution is still the only option (no competing packages). However, should @j0hannes add me to the AUR repo, I would be more than happy to push my suggestion. Otherwise, they can obtain mine easily. By the way, thesed
line will not be needed once this goes upstream.Edit. In fact, there might be a small update later to the statement:
Both packages install precompiled jar files and add a command and a .desktop file to the OS.
if @j0hannes decides to borrow my solution (i.e., building from source).
I actually wouldn't do that since I wrote the AUR package specifically to avoid doing the compilation with gradle, which I found rather annoying for several reasons. It also failed to build frequently. I never had a problem with the pre-compiled jar so far -- apart from bugs in the application itself.
You might want to contribute to jabref-git instead.
I released a new PKGBUILD the day after that comment. Since then, it's working fine for me.
Just now I have run pacman -Rscn jabref
and done the following:
~> git clone https://aur.archlinux.org/archlinux-java-run /tmp/archlinux-java-run
~> cd /tmp/archlinux-java-run
/t/archlinux-java-run> makepkg --syncdeps --clean --cleanbuild --install
# skip output
/t/archlinux-java-run> git clone https://aur.archlinux.org/jabref-latest /tmp/jabref-latest
/t/archlinux-java-run> cd /tmp/jabref-latest
/t/jabref-latest> makepkg --syncdeps --clean --cleanbuild --install
# skip output
/t/jabref-latest> pacman -Qi jabref-latest
Name : jabref-latest
Version : 20190912-1
Description : GUI frontend for BibTeX, written in Java; latest master version from git
Architecture : any
URL : https://www.jabref.org/
Licenses : MIT
Groups : None
Provides : jabref
Depends On : archlinux-java-run>=4 java11-openjfx sh atk bzip2 cairo expat fontconfig freetype2 fribidi
gcc-libs gdk-pixbuf2 glib2 glibc graphite gtk2 harfbuzz libdatrie libffi libpng libthai
libutil-linux libx11 libxau libxcb libxcomposite libxcursor libxdamage libxdmcp libxext
libxfixes libxi libxinerama libxrandr libxrender libxtst pango pcre pixman zlib
Optional Deps : gsettings-desktop-schemas: For web search support [installed]
Required By : None
Optional For : None
Conflicts With : jabref
Replaces : None
Installed Size : 103,14 MiB
Packager : Unknown Packager
Build Date : tor 12 sep 2019 12:29:14
Install Date : tor 12 sep 2019 12:30:33
Install Reason : Explicitly installed
Install Script : No
Validated By : None
When I try to run JabRef from dmenu (desktop file) it does not open anything (I am running i3-wm
). Then I open a terminal and run/get the following:
~> which jabref
/usr/bin/jabref
~> cat /usr/bin/jabref
#!/bin/sh
/usr/bin/archlinux-java-run --min 11 --max 11 -- -jar /usr/share/java/jabref-latest/JabRef-20190912.jar "$@"
~> jabref
Error: Could not find or load main class org.jabref.org.jabref.JabRefLauncher
Caused by: java.lang.ClassNotFoundException: org.jabref.org.jabref.JabRefLauncher
which brings me back to my first comment above and which, as @tobiasdiez mentions in his comment, is expected:
With modularized Java 11 applications, the
jar
file does no longer work / is no longer the supported distribution mechanism. Instead, you should create a runtime image usinggradle jlink
and then run it viajava -m org.jabref/org.jabref.JabRefLauncher
.
This was the reason why I needed to write a new PKGBUILD
. Your PKGBUILD
, even though it might be working for you, is using the (apparently now unsupported) jar
mechanism.
Anyways... Thank you for your prompt response and making your points.
Cheers.
Ok, I think it should be sufficient to package only build/image
, i.e. change
cp -R "${pkgname}/build" "${pkgdir}/opt/jabref"
to
cp -R "${pkgname}/build/image" "${pkgdir}/opt/jabref"
This should reduce the size of the package considerably. (For example, jlinkbase
is used during jlink
but not required afterwards.)
As a side note, I will experiment with jpackage during the next days. This should give rpm
or deb
packages for linux (not sure if they are also usable with arch).
which brings me back to my first comment above and which, as @tobiasdiez mentions in his comment, is expected:
With modularized Java 11 applications, the
jar
file does no longer work / is no longer the supported distribution mechanism. Instead, you should create a runtime image usinggradle jlink
and then run it viajava -m org.jabref/org.jabref.JabRefLauncher
.
Thanks for pointing that out. I wasn't aware of it. What is the point of offering jar files in https://builds.jabref.org/master/ then? I am supposed to download them, decompose them and run gradle on them? That doesn't sound like a solution for everybody.
This was the reason why I needed to write a new
PKGBUILD
. YourPKGBUILD
, even though it might be working for you, is using the (apparently now unsupported)jar
mechanism.Anyways... Thank you for your prompt response and making your points.
I'm happy about any suggestion how to use the jar file provided by builds.jabref.org without executing it with java.
We have only recently discovered that the jar
file does not work. We should change the build so that the runtime image (build/image
) generated by jlink
is published instead. @Siedlerchr do you have a bit of time to work on this today? If not I'll have a look at the weekend.
I will try to look into it today. Maybe it's also possible to create the archive using install4j.
We have only recently discovered that the
jar
file does not work. We should change the build so that the runtime image (build/image
) generated byjlink
is published instead. @Siedlerchr do you have a bit of time to work on this today? If not I'll have a look at the weekend.
So it broke recently? Because I'm still able to run the version installed a week ago.
Could anyone of you try if the .sh script works? (I currently don't have a linux system at hand) http://builds.jabref.org/install4jlinux/ It should be a complete installer.
It runs, and open a graphical installer that looks like the ones that Windows has. I canceled it when it wanted to write to system directories; which is not possible for a regular user and I would never execute a script like that with root.
I looked into the code and there seems to be no other option than running that installer. So, from my point of view, it's of little use for linux users. I don't see how to use it for packaging Jabref.
I totally agree with @j0hannes on the shell-script solution. IMHO, you (devs) should just help package maintainers write their own scripts to package your applications. I mean, if I know how to build your application, it will be trivial for me to package it for my system. Not to mention the fact that graphical installers are a big problem for automated packaging processes.
Yes, I know that graphical installers are not the best solution for unix. It was just a try. I hoped that the installer created a simple start script. I will experiment further and hope I can get the jlink stuff zipped together.
Once jpackager works, I do think we can completely get rid of intalll4j (also on Windows). That being said, I managed to add a build pipeline that produces a zip file of the build/image
folder. The build artifacts are available here: https://dev.azure.com/JabRef/JabRef/_build/results?buildId=2&view=artifacts
After downloading and unpacking, the following should work:
cd image/bin
./JabRefMain
It would be nice if you could try this. If it works, then I'll add the necessary code to publish these zip files to builds.jabref.org
.
It runs. This is the log:
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
ERROR ThemeLoader Could not watch css file for changes jrt:/org.jabref/org/jabref/gui/Base.css
java.lang.UnsupportedOperationException
at java.base/jdk.internal.jrtfs.JrtPath.register(Unknown Source)
at java.base/jdk.internal.jrtfs.JrtPath.register(Unknown Source)
at org.jabref/org.jabref.gui.util.DefaultFileUpdateMonitor.addListenerForFile(Unknown Source)
at org.jabref/org.jabref.gui.util.ThemeLoader.addAndWatchForChanges(Unknown Source)
at org.jabref/org.jabref.gui.util.ThemeLoader.installCss(Unknown Source)
at org.jabref/org.jabref.JabRefGUI.openWindow(Unknown Source)
at org.jabref/org.jabref.JabRefGUI.<init>(Unknown Source)
at org.jabref/org.jabref.JabRefMain.start(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.jabref.merged.module/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(Unknown Source)
at org.jabref.merged.module/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at org.jabref.merged.module/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at org.jabref.merged.module/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
ERROR ThemeLoader Could not watch css file for changes jrt:/org.jabref/org/jabref/gui/Base.css
java.lang.UnsupportedOperationException
at java.base/jdk.internal.jrtfs.JrtPath.register(Unknown Source)
at java.base/jdk.internal.jrtfs.JrtPath.register(Unknown Source)
at org.jabref/org.jabref.gui.util.DefaultFileUpdateMonitor.addListenerForFile(Unknown Source)
at org.jabref/org.jabref.gui.util.ThemeLoader.addAndWatchForChanges(Unknown Source)
at org.jabref/org.jabref.gui.util.ThemeLoader.installCss(Unknown Source)
at org.jabref/org.jabref.gui.util.BaseDialog.<init>(Unknown Source)
at org.jabref/org.jabref.gui.help.AboutDialogView.<init>(Unknown Source)
at org.jabref/org.jabref.gui.help.AboutAction.execute(Unknown Source)
at org.jabref/org.jabref.gui.actions.JabRefAction.lambda$new$2(Unknown Source)
at org.jabref.merged.module/org.controlsfx.control.action.Action.handle(Unknown Source)
at org.jabref.merged.module/org.controlsfx.control.action.Action.handle(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at org.jabref.merged.module/javafx.event.Event.fireEvent(Unknown Source)
at org.jabref.merged.module/javafx.scene.control.MenuItem.fire(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at org.jabref.merged.module/javafx.event.Event.fireEvent(Unknown Source)
at org.jabref.merged.module/javafx.scene.Scene$MouseHandler.process(Unknown Source)
at org.jabref.merged.module/javafx.scene.Scene$MouseHandler.access$1200(Unknown Source)
at org.jabref.merged.module/javafx.scene.Scene.processMouseEvent(Unknown Source)
at org.jabref.merged.module/javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.jabref.merged.module/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
at org.jabref.merged.module/com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
at org.jabref.merged.module/com.sun.glass.ui.View.notifyMouse(Unknown Source)
at org.jabref.merged.module/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at org.jabref.merged.module/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
@tobiasdiez it does run. You were a bit faster than I was (I was also trying my PKGBUILD
in the meantime, but no whining ;))
I have prepared a and a tar.gz
file on my machine for you guys to try (Windows users). I was also checking Travis documentation to come up with this zip
file.travis.yml
solution (well, I got rid of the testing scripts on purpose to speed up the process when experimenting):
dist: bionic
language: java
jdk: openjdk11
script:
- ./gradlew jlink
- mv build/image jabref
- zip -r jabref-master.zip jabref
- tar cvzf jabref-master.tar.gz jabref
deploy:
provider: releases
api_key: ${GITHUB_TOKEN}
file:
- jabref-master.zip
- jabref-master.tar.gz
skip_cleanup: true
overwrite: true
Travis automatically runs ./gradlew assemble
during the install
step.
Edit.
Thanks for the feedback. I will try to modify our Circle CI script to include that
I now updated the Circle CI config so that the linux build using jlink is also uploaded to http://builds.jabref.org/master/
The file is always named JabRef-linux-<branch>-latest.tar.gz
So you can adjust your wget scripts ;)
Should we close this issue? What do you think?
I think is now resolved, so I will close it. Would just be nice if you could update the information in the help as JabRef ships now with all required jdk libs. This should probably work for other distros as well.
There are probably a few more changes coming the next few days when I'll get the github actions stuff and jpackage working.
So we better hold and wait for the final version to be available before trying to package it?
Depends a bit. If you could simply use deb
or rpm
packages, then just wait since they will be created by jpackage. If you need to package the runtime image generated by jlink
anyway, then I would suggest you already go ahead and use the tar.gz
. The name of this file might change in the near future, but apart from this there shouldn't be any huge changes in the workflow.
Debian packages are fine to convert; that might be the more reliable way. The filename will remain stable as it has been for the jar, right?
So I've managed to make jpackage work on all platforms. @j0hannes @aytekinar what would be the most convenient distribution format for package maintainers and users on linux:
(one of the questions is if the last one is necessary or if the first two are actually sufficient).
Refs: https://github.com/JabRef/jabref/pull/5312#issuecomment-531394599 (you are invited to try out the builds referenced there)
@tobiasdiez IMHO, the last one is necessary and sufficient. Of course, Arch's packaging system knows how to interpret/unpack deb
and rpm
packages/archives so that we can just point to those files in PKGBUILD
and do necessary directory changes (move parts to places which Arch suggests). However, a tar
or tar.gz
archive is more generic and already enough. In a sense, you decide (as the developers) what files are needed for the application to run, pack them properly, and let the package maintainers do their work. deb
is good for your Debian-based users (Debian and *buntu distros) while rpm
will cover RedHat-based users (RedHat, Fedora, etc.). In any case, if you want to let other distros use JabRef easily, you
tar.gz
in this case) that contains the self-contained cross-platform compatible binaries.For this reason, I think that tar.gz
is necessary and sufficient. A nice talk on this is here if you have some time to spend and smile :smile:
I tried to provide a working jabref-git PKGBUILD for Arch Linux, but it fails at the gradle jlink step. This is what I have:
pkgname=jabref-git
pkgver=5.0alpha.r99.g381f0f3f08
pkgrel=1
pkgdesc="GUI frontend for BibTeX, written in Java -- built from git"
arch=('any')
url="https://www.jabref.org"
license=('MIT')
depends=('java-environment>=11' 'java11-openjfx')
makedepends=('git' 'gradle')
optdepends=('gsettings-desktop-schemas: For web search support')
provides=('jabref')
conflicts=('jabref')
source=("${pkgname%-git}::git+https://github.com/JabRef/jabref.git"
git+https://github.com/citation-style-language/locales.git
git+https://github.com/citation-style-language/styles.git
"${pkgname%-git}.desktop"
"${pkgname%-git}.sh")
md5sums=('SKIP'
'SKIP'
'SKIP'
'5f76feb6b2f66a2ea8b52bca999a934f'
'b7c7fca66fe7e0a466df1f6b3c0539ff')
pkgver() {
cd ${pkgname%-git}
git describe --tags | sed 's+-alpha-+alpha.r+'|cut -c2-|tr - .
}
prepare() {
cd ${pkgname%-git}
_release=$(sed -n 's/.*version = \"\(.*-dev\)\"/\1/p' build.gradle)
[[ -d locales ]] || ln -s ../locales locales
[[ -d styles ]] || ln -s ../styles styles
git submodule update --init
}
build() {
cd ${pkgname%-git}
gradle assemble
gradle jlink
}
# package() {
# cd ${pkgname%-git}
# find "${srcdir}/${pkgname%-git}/build/releases" \
# -iname "JabRef-${_release}.jar" \
# -exec install -Dm644 {} "$pkgdir"/usr/share/java/jabref/JabRef.jar \;
# install -Dm755 "$srcdir"/jabref.sh "$pkgdir"/usr/bin/jabref
# install -Dm644 "$srcdir"/jabref.desktop \
# "$pkgdir"/usr/share/applications/jabref.desktop
# install -Dm644 "build/resources/main/icons/${pkgname%-git}.svg" \
# "$pkgdir"/usr/share/pixmaps/${pkgname%-git}.svg
# install -Dm644 LICENSE.md "$pkgdir"/usr/share/licenses/${pkgname}/LICENSE
# }
package() {
cd "${srcdir}"
install -d "${pkgdir}/opt"
cp -R "${pkgname}/build" "${pkgdir}/opt/jabref"
install -D jabref.desktop "${pkgdir}/usr/share/applications/jabref.desktop"
install -D jabref.png "${pkgdir}/usr/share/pixmaps/jabref.desktop"
}
this is the error message
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':jlink'.
> Process 'command '/usr/lib/jvm/java-11-openjdk/bin/jlink'' finished with non-zero exit value 1
* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':jlink'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:166)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:163)
at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:191)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:156)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:108)
at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
at org.gradle.api.internal.tasks.execution.StartSnapshotTaskInputsBuildOperationTaskExecuter.execute(StartSnapshotTaskInputsBuildOperationTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:94)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:95)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
Caused by: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/java-11-openjdk/bin/jlink'' finished with non-zero exit value 1
at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:409)
at org.gradle.process.ExecResult$assertNormalExitValue.call(Unknown Source)
at org.beryx.jlink.impl.JlinkTaskImpl.runJlink(JlinkTaskImpl.groovy:83)
at org.beryx.jlink.impl.JlinkTaskImpl.execute(JlinkTaskImpl.groovy:52)
at org.beryx.jlink.JlinkTask.jlinkTaskAction(JlinkTask.groovy:120)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:49)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:42)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:717)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:684)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$5.run(ExecuteActionsTaskExecuter.java:476)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:461)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:444)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:93)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:237)
at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$1(ExecuteStep.java:33)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:33)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:58)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:33)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:39)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:35)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:45)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:31)
at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:208)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:70)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:45)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:43)
at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:32)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96)
at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:54)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:90)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:48)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:69)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:47)
at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:140)
... 35 more
@stefanhusmann, please check my PKGBUILD. It is building on my machine with i3-wm
as the window manager. Note that JabRef is using submodules now, and hence, git submodule update --init
on this line should be enough (i.e., you should not track submodules separately). Moreover, you do not need to depend on java11-openjfx
or similar anymore --- making them make dependencies should be enough.
I checked it, an I get the same error message as with my PKGBUILD.
Please check if gradle is running under the correct java version: ./gradlew -v
gradlew picks the Gradle 5.6, which is coming with the jabref sources, but I also tried with gradle 5.6.2 which is coming with the official Arch Linux package.
Build time: 2019-08-14 21:05:25 UTC Revision: f0b9d60906c7b8c42cd6c61a39ae7b74767bb012
Kotlin: 1.3.41 Groovy: 2.5.4 Ant: Apache Ant(TM) version 1.9.14 compiled on March 12 2019 JVM: 11.0.4 (Oracle Corporation 11.0.4+11) OS: Linux 5.2.14-arch1-1-ARCH amd64
Hello, I now was able to build jabref. It seems that sowehow the java11-openjfx (the system package delivered by Arch Linux) interferes with the build process. It needs to be uninstalled.
JabRef is also launchable with /opt/jabref/bin/JabRefMain, but something still seems wrong:
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using Simple
Logger to log to the console...
ERROR ThemeLoader Could not watch css file for changes jrt:/org.jabref/org/jabref/gui/Base.css
java.lang.UnsupportedOperationException
at java.base/jdk.internal.jrtfs.JrtPath.register(Unknown Source)
at java.base/jdk.internal.jrtfs.JrtPath.register(Unknown Source)
at org.jabref/org.jabref.gui.util.DefaultFileUpdateMonitor.addListenerForFile(Unknown Source)
at org.jabref/org.jabref.gui.util.ThemeLoader.addAndWatchForChanges(Unknown Source)
at org.jabref/org.jabref.gui.util.ThemeLoader.installCss(Unknown Source)
at org.jabref/org.jabref.JabRefGUI.openWindow(Unknown Source)
at org.jabref/org.jabref.JabRefGUI.<init>(Unknown Source)
at org.jabref/org.jabref.JabRefMain.start(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(Unknown Source)
at org.jabref.merged.module/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.jabref.merged.module/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(Unknown Source)
at org.jabref.merged.module/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at org.jabref.merged.module/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at org.jabref.merged.module/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
The log4j error should be fixed in the latest master version.
Generally you should only need to run ./gradlew assemble
and gradlew jlink
to build jabref. The latter one creates the necessary dependencies and launch configuration.
@j0hannes Could you update the package?
@homocomputeris, I will, I have just been travelling for two weeks now.
@j0hannes Thanks a lot!
@homocomputeris, I have adapted the package, could you try?
@j0hannes Great, it works, thanks a lot!.
Two small issues: there is no .desktop
file in Gnome 3 anymore, and
ERROR StatusLogger Log4j2 could not find a logging implementation.
Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
which is a dependency, probably?
It's also a bit laggy and slowish, but it's probably JabRef's problems.
@homocomputeris The logger issue is a known problem. We are working on it. Regarding the desktop file see #5444
It turns out that in j0hannes's package the desktop entry still exists and this just works:
[Desktop Entry]
Name=JabRef
GenericName=BibTeX Editor
Type=Application
Terminal=false
Icon=JabRef
Exec=/usr/bin/jabref
which is fine for me ATM.
@homocomputeris, there should be a .desktop file: /usr/share/applications/JabRef.desktop
I am on an Arch Linux machine with the following:
Steps to reproduce the behavior:
gradle releaseJar
orgradle shadowJar
(see log)java -jar build/releases/JabRef-5.0-dev.jar
I have a failure with the following error:
Log File
``` > Task :buildSrc:compileJava NO-SOURCE > Task :buildSrc:compileGroovy > Task :buildSrc:processResources NO-SOURCE > Task :buildSrc:classes > Task :buildSrc:jar > Task :buildSrc:assemble > Task :buildSrc:compileTestJava NO-SOURCE > Task :buildSrc:compileTestGroovy NO-SOURCE > Task :buildSrc:processTestResources NO-SOURCE > Task :buildSrc:testClasses UP-TO-DATE > Task :buildSrc:test NO-SOURCE > Task :buildSrc:check UP-TO-DATE > Task :buildSrc:build > Configure project : Found module name 'org.jabref' > Task :generateBibtexmlSource > Task :generateBstGrammarSource > Task :generateEndnoteSource > Task :generateMedlineSource > Task :generateModsSource > Task :generateSearchGrammarSource > Task :generateSource > Task :compileJava Note: Some input files use or override a deprecated API. Note: Recompile with -Xlint:deprecation for details. Note: Some input files use unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. > Task :processResources > Task :classes > Task :shadowJar > Task :releaseJar Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0. Use '--warning-mode all' to show the individual deprecation warnings. See https://docs.gradle.org/5.6.1/userguide/command_line_interface.html#sec:command_line_warnings BUILD SUCCESSFUL in 37s 10 actionable tasks: 10 executed ```