-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FONTDIR not working when used by JRuby in an OSGI environment #45
Comments
Hi @PartTimeDataScientist - thanks for using Sorry you're running into problems. The Unfortunately my familiarity with jruby/OSGI is next to zero, so I'm in unfamiliar territory here. I'd be open to allowing configuration of the font directory, but I'd like to understand the root problem a bit more first. In your case does the I do see that If we do end up allowing configuration of the font directory, it may be worthwhile to expose a good interface something like: Prawn::Icon.configure do |config|
config.data_directory = '/path/to/somewhere'
end I'll look into this over the next few weeks to see what options we have. PRs would definitely be welcome as well! |
Thanks for looking into it @jessedoyle, I'll try to assist where possible. I've seen issue #16 as there aren't that many issue to browse for The OSGi bundle I am working on is actually a plugin for Eclipse where I am including asciidoctorj-pdf-1.5.3.jar which in turn contains (among others) the gems prawn-icon-2.5.0 and asciidoctor-pdf-1.5.3. Both gems are using fonts which are located in the At first glance asciidoctor is loading fonts and theme-file in
|
This doesn't feel like the right repository to report this issue. I'd say this is more of an issue with AsciidoctorJ PDF, and maybe just Asciidoctor PDF. |
I know that I understand not nearly enough of the interaction between Asciidoctor and Prawn::Icon to discuss your judgment. I just thought this would be the right place as the exception is raised by Prawn::Icon and modifying the base.rb file allowed me to find a workable solution. I'll gladly report this as an issue for AsciidoctorJ PDF or Asciidoctor PDF if you think that would be the more appropriate spot. |
If you were using Prawn::Icon by itself in JRuby/OSGi, then I would agree the place is here. But by bringing Asciidoctor PDF examples in here, you have stepped outside the scope of what this project should have to worry about. That's not to say a code change might be required here, but we are distracting this project with concerns that really start from Asciidoctor PDF. |
@jessedoyle wrote:
That doesn't make it non-portable. Ruby already handles path normalization across platforms. The main issue I see is how you are getting to the base location of the gem. What we do in Asciidoctor is define the ROOT_DIR of the gem in the entrypoint script using:
Then we build paths from there. Within a jar, JRuby builds the absolute path in a way that allows it to reference other files in the jar. You definitely don't have to worry about that as a gem author. |
Gem.datadir is an entirely different location which is not inside the gem. I've been tripped up by this in the past. I have never found Gem.datadir to be useful. |
A consumer of a gem should never have to worry about having to set up paths so that the gem can access its own files. This can be achieved by defining the ROOT_DIR correctly as I have shown (and as @PartTimeDataScientist pointed out we do in the theme loader for Asciidoctor PDF). |
@PartTimeDataScientist After studying this issue more closely, I see that your point about this being an issue with Prawn::Icon is likely correct. I think the fact that you were talking about Asciidoctor PDF made it seem like you were citing a problem that had to do with how it is integrated into Asciidoctor PDF, but that's not actually the case. So I retract my earlier criticism about where you filed this issue. |
Thanks for the input! Yes, I think making the font directory configurable is a reasonable request - therefore I think we should keep this issue open until there's a mechanism for that. @mojavelinux - Nice, that's good to know about Ruby path normalization. I guess I've always taken that for granted. I've used |
Sounds like a good approach. |
Happy to hear that. :-) I already had the feeling that I always overlook something when reporting/discussing the problems I have with integrating asciidoctor in my little project. This particular issue has actually bothered me for quite a while but with your hints it sounds as if there is a straightforward way for improving the situation and I can live with my workaround for the moment to work on other topics. @jessedoyle With the comments of @mojavelinux I think this might also be split up in two issues
|
resolves #45 * Introduce a standard gem configuration interface that allows users to set an alternate font directory as follows: ```ruby Prawn::Icon.configure do |config| config.font_directory = '/foo/bar' end ``` * Formally deprecate the `FONTDIR` and `SHIMS` constants and replace with memoized class variables. We're only keeping them around so as to not release a breaking change. * Bump version to 2.6.0. * Fix a bug with directory pathing in some environments because the path was built assuming consistent namespacing. We now use `Gem::Specification#full_gem_path` to handle the inconsistencies. * Disable the rubocop `Layout/MultilineMethodCallIndentation` check as it adds more whitespace than I prefer.
@PartTimeDataScientist - I've got a PR open that I think should address both issues mentioned above. The font directory can (optionally) be configured as follows: Prawn::Icon.configure do |config|
config.font_directory = '/path/to/fonts'
end The PR should also resolve the issue with the assumptions Prawn::Icon used when finding the font directory. I think this should resolve your issue in JRuby/OSGI. @mojavelinux - I'm unfamiliar with the environment. Is it possible to just point the i.e. # in Gemfile
gem 'prawn-icon', git: 'https://github.com/jessedoyle/prawn-icon.git', branch: 'gh-45' |
@jessedoyle I thought we worked out that the directory does not need to be configured. Sure, it might be nice to be able to configure it for running the tests in say a specialized environment like Linux packaging. But for normal usage, it should just work. As @PartTimeDataScientist pointed out, the internal gem paths in Asciidoctor PDF work fine in a JRuby/OSGi environment, so prawn-icon can do the same. |
@mojavelinux - For sure I definitely understand the configuration part is not needed. My PR makes the configuration piece entirely optional, with sane defaults to the gem's internal data directory. I opted to implement the configuration of the font directory because I found @PartTimeDataScientist's argument compelling:
Essentially one can now implement custom icon fonts given that some elbow grease has been put in to generate the necessary foundation (unicode mapping file, etc.). The PR also implements path resolution using |
Ah, thanks for clarifying. In that case, fantastic! |
Just did a quick test and replaced all the ruby files in the
|
I think it's a timing issue. The code is called while it is being loaded, so it is not yet loaded and thus not present in Gem.loaded_specs. The assignment would have to be deferred until first use (after the gem is loaded). |
Interesting, I'll look into it over the next few days. As a fallback we can definitely use @mojavelinux's suggestion. |
@PartTimeDataScientist - Sorry to keep bothering you, do you mind trying to run Basically just throw a line like this above this line: puts Gem.loaded_specs.keys |
@jessedoyle - Sure thing! Trying to help where I can. I modified base.rb and configuration.rb to read as below. Interestingly only Hope you can make sense of the results... base.rb
configuration.rb
output
font_data.rb - "workaround version"
output
|
Thanks for the help @PartTimeDataScientist. Rubygems should be loading all required dependencies by that point, so something is definitely a little broken. I'll do a bit of research though and should be able to come up with a solution in a few days. |
resolves #45 * Introduce a standard gem configuration interface that allows users to set an alternate font directory as follows: ```ruby Prawn::Icon.configure do |config| config.font_directory = '/foo/bar' end ``` * Formally deprecate the `FONTDIR` and `SHIMS` constants and replace with memoized class variables. We're only keeping them around so as to not release a breaking change. * Fix a bug with directory pathing in some environments because the path was built assuming consistent namespacing. We now use `Gem::Specification#full_gem_path` to handle the inconsistencies. * Disable the rubocop `Layout/MultilineMethodCallIndentation` check as it adds more whitespace than I prefer.
resolves #45 * Introduce a standard gem configuration interface that allows users to set an alternate font directory as follows: ```ruby Prawn::Icon.configure do |config| config.font_directory = '/foo/bar' end ``` * Formally deprecate the `FONTDIR` and `SHIMS` constants and replace with memoized class variables. We're only keeping them around so as to not release a breaking change. * Fix a bug with directory pathing in some environments because the path was built assuming consistent namespacing. We now use `Gem::Specification#full_gem_path` to handle the inconsistencies. * Disable the rubocop `Layout/MultilineMethodCallIndentation` check as it adds more whitespace than I prefer.
resolves #45 * Introduce a standard gem configuration interface that allows users to set an alternate font directory as follows: ```ruby Prawn::Icon.configure do |config| config.font_directory = '/foo/bar' end ``` * Formally deprecate the `FONTDIR` and `SHIMS` constants and replace with memoized class variables. We're only keeping them around so as to not release a breaking change. * Fix a bug with directory pathing in some environments because the path was built assuming consistent namespacing. We now use `Gem::Specification#full_gem_path` to handle the inconsistencies. * Disable the rubocop `Layout/MultilineMethodCallIndentation` check as it adds more whitespace than I prefer.
resolves #45 * Introduce a standard gem configuration interface that allows users to set an alternate font directory as follows: ```ruby Prawn::Icon.configure do |config| config.font_directory = '/foo/bar' end ``` * Formally deprecate the `FONTDIR` and `SHIMS` constants and replace with memoized class variables. We're only keeping them around so as to not release a breaking change. * Fix a bug with directory pathing in some environments because the path was built assuming consistent namespacing. We now use `Gem::Specification#full_gem_path` to handle the inconsistencies. * Disable the rubocop `Layout/MultilineMethodCallIndentation` check as it adds more whitespace than I prefer.
I'm hoping to cut a new release and (partially) resolve this issue for you. The fact that With that being said, I added a failsafe mechanism in #46 in the event that the gemspec hasn't been loaded yet. In that case, we simply revert to the previous path resolution behaviour. I believe the key to solving your issue will be with the configurable font directory that was added: i.e. Prawn::Icon.configure do |config|
config.font_directory = '/absolute/path/to/font/directory'
end My suggestion would be to utilize the configuration of the font directory above to be able to set up the proper pathing for your environment. For now I'm going to close this issue. Feel free to comment and we can reopen if necessary. Thanks! |
feat(fonts) - Configuration of Font Directory
To my knowledge, there is no such quirk in JRuby. I verified using JRuby 9.2 with Asciidoctor PDF 1.5.3 and the following call works when placed at the very top of the prawn/icon.rb. Gem.loaded_specs.fetch('prawn-icon').full_gem_path Unless it can be proved that this call is problematic on JRuby with a sample project, we must assume that there is a misconfiguration elsewhere that would cause this to fail. While allowing the font directory to be configured is certainly a nice enhancement to accommodate certain use cases, I would not worry about adding a defensive callback if Gem.loaded_specs doesn't find prawn-icon. |
Hi @jessedoyle: I just found the time to test your new release. In order to run the test I've replaced all praw-icon ruby files in the Asciidoctor PDF 1.5.3 JAR with the ones from the new release and ended up with exactly the same behavior as before: :-/ Looks like the Asciidoctor way of getting the full_gem_path is the most stable way of getting the relevant directory in the JRuby case...
|
While updating the libraries on my module I figured that the root cause of the font-files not being found (at least for the 3.0.0 version - didn't test for the old one as of yet) is not the way how the gem folder is defined but the ".glob" statement searching for .ttf-files in line 68 of font_data.rb which is not working inside a .jar file! I've found some issues regarding DIR.* not working inside .jar-files but most old and often claimed to be fixed.
Nonetheless this allows to propose a generic solution to the problem. I've hard-coded the .ttf-file belonging to each set in my internal version by introduing a tiny accessory function font_path() and a modification of the path() function:
That works stable for my application where prawn-icon is included within asciidoctorj-pdf.jar for all icon sets. I envision that this approach should work for the other usecases as well and might even be more stable and flexible e.g. regarding .otf font files for specific sets. @jessedoyle Please let me know what you think about this idea. I didn't submit it as a PR as of yet as I don't have the ability to test the code outside my usecase but could easily do so if you agree with this approach. |
Hey @PartTimeDataScientist, I'm glad to hear that you've narrowed in on the issue (and that you've found a monkeypatch/solution that works for you)! I am surprised that
Are you able to include the code snippet above in your own app/code as a monkeypatch? I don't suspect that it will cause any issues for you in the future. Thanks again! |
Hi @jessedoyle, thanks for looking into it. I did find the same issue that you refer to but that is claimed to be fixed since years ago. There is a newer issue but that only refers to using the classpath: notation and not the uri:classloader: notation so that shouldn't be the case here. Nonetheless Dir.* and jRuby and .jar-Files don't seem to be best friends... I can live with monkey patching the gem inside the asciidoctorj-pdf.jar but nonetheless would prefer to have a more general solution. One other idea that I had after finding the "glob" as root cause was to define the required font file in the set.yml file directly. Although I guess that this would also be a not too complex solution it was out of reach of my limited ruby skills and understanding of the library. :-/ I was already happy that I could debug the issue using plenty of "puts" statements throughout the whole code... :-) This would still allow users to add their own font (they would have to create the shim-file anyway) without the need for a code change while getting rid of the glob statement. It would also facilitate geting rid of the font subdirectories as you could place all the *.yml together with the required *.ttf files in a single /fonts directory: Thinking this even further it should be possible to get rid of the various shim files and subdirectories and have a single "sets.yml" in a fonts directory together with the required *.ttf or *.otf files which IMHO would notably decrease the complexity of font path resolution.
|
The .glob('*.ttf') command doesn't work nicely in all environments (e.g. within the .jar of asciidoctorj - see jessedoyle#45). This modification removes the .glob command by hardcoding the respective .ttf file
While trying to use AsciidoctorJ PDF in an OSGi environment font based icons are not rendered properly. Prawn::Icon is trying to access the .ttf-file from "uri:classloader:/gems/prawn-icon-2.5.0/data/fonts/fas/*.ttf" which doesn't work in that case (
org.jruby.exceptions.StandardError: (UnknownFont) Icon font not found for set: ...
).One possible solution that seems to do the trick for me is to store the icon-fonts in an extra folder (inside the OSGi-bundle) and provide Prawn::Icon with the location. This can be done by setting a system property in Java and testing if the corresponding ENV_JAVA is set on the Ruby side. In addition, this should provide an easy way to use custom icon fonts in a configurable location (provided one has the ttf and created a suitable .yml shim). Using more (custom) icon fonts seems to be interesting as it is discussed in at least two Asciidoctor issues (#539 and #3461)
So for my case I have modified base.rb to read like follows
As I might have overlooked side effects or perhaps did not find the optimal solution I didn't submit it as a PR but I wanted to have my solution documented in case someone is running into a similar issue. Feel free to close the issue if you think it is not relevant for the general public as I have found a suitable workaround for me.
The text was updated successfully, but these errors were encountered: