Having issues importing and using
AndroidDeveloperLB opened this issue · 40 comments
I wanted to see how to create hyperlinks, so there are these sample PDF files:
https://github.com/phax/ph-pdf-layout/tree/master/example-files/plexternallink
And also a sample code:
So I copied this a bit into a new Android app project, and I also tried to use this in the gradle file (kts formant):
implementation("com.helger:ph-pdf-layout4:5.2.2")}
It can't find the classes.
The docs say to use it this way.
Also it's mentioned here:
https://search.maven.org/artifact/com.helger/ph-pdf-layout4/5.2.2/jar?eh=
But it's weird because the latest version is also said to be 7.1.0...
Attached the problematic sample project. I can also use Java if you wish. Kotlin should be fine though, as it can handle Java easily.
I also tried to reach Jitpack as it might be able to fetch the library, but it failed:
https://jitpack.io/#phax/ph-pdf-layout
What is going on ? What should I use? Maybe the docs weren't updated?
Hi, my knowledge about building Android applications is limited.
However, I spotted an error in the badges, so now the right version number is displayed.
For historical reasons I needed to make a breaking change from v3 to v4 so that both the package name and the artifact name were altered (adding a 4
at the end as in ph-pdf-layout4
). That's why your example doesn't work, because the Java package name was also modified. This verisoning scheme was kept until version 5 - see https://search.maven.org/search?q=ph-pdf-layout for the confusion.
Starting from v6 I reverted to the "original" system of using just "ph-pdf-layout", so for Java 8 please use:
implementation("com.helger:ph-pdf-layout:6.0.3")
and for Java 11 onwards use
implementation("com.helger:ph-pdf-layout:7.1.0")
Hope that makes a bit of sense :)
@phax Now I have a different issue.
It seems it relied on "java.awt.*" stuff, and this is limited on Android, sadly.
For example, there is no java.awt.Color (used for setFillColor, setBorder, for example). Instead there is android.graphics.Color, or I could just use ARGB value (Integer).
Sadly here in this library both of these aren't available.
In addition, there is BufferedImage used for PLImage. On Android, there is android.graphics.Bitmap , Or I could just provide 2-dimentional array of Integers (each is a pixel in ARGB form), or any other thing you wish.
Are there alternative to those in this library?
Can I avoid using "java.awt.*" stuff?
@phax Maybe you know of an alternative to this library, that could work even on Android?
I just want to be able to print a table with texts and links... Maybe also some images as a bonus.
No, I am not aware of really similar libraries that I can recommend. Let me see if can operate this class away - give me some days. I am on vacation atm
That would be awesome !
But I think it's hard, no?
No, it's not too hard. Its just a backwards incompatible change...
I hope you succeed.
Please have alternatives for each usage of "awt".
Please see release 7.3.0 - removes java.awt.color.
Caution: don't use PDF/A - this still requires java.awt.* stuff.
Ah yes - for color use the new class PLColor
- same API as color. For PLImage
there is no replacement, as the underlying PDFBox
library also uses the java.awt.BufferedImage
. As PLImage
is a very small class, you may find a solution like PLImage2
that creates the images based on a different source???
@phax About PLColor, thank you. Seems it support RGB. Does it support alpha too? Or PDF doesn't support such a thing?
I personally don't need it (at least not for what I'm planning, which should be very small), but maybe people will find it useful.
About PLImage2 , I can't find it after changing the dependency. Sure it's there?
Also, what "different source" ?
PDF does support alpha channel - may be later. I used Color also just in RGB mode.
Regarding PLImageXXX
- this is for your to do :) Find an Android library that does the trick for you. I can't help you, as BufferedImage is the best I am aware of and I can't move away from it
@phax You mean I should extend from AbstractPLImage ?
But then I need to implement getXObject, yet PDImageXObject is marked as final , and none of its CTORs seem to offer a way to give it a simple array of pixels data. In PDImageXObject there are a lot of references to awt, too.
Another option would be to use LosslessFactory.createFromImage (which is the most suitable as it supports all kinds of bitmaps), but again, it still uses BufferedImage...
I don't see how to get away from awt when the classes are very strict...
Are you sure it's possible?
I have no idea if it is possible or not. I don't know the Android runtime. You need to do some investigations...
@phax I didn't talk about Android being the issue.
I talked about the classes being used here.
I investigated those classes and wrote you that they are too closed to being extended, and they use awt...
I'm sure that in every framework, there is the Bitmap representation as an array of pixels, with width and/or height being input too.
I can see org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory.createFromRGBImage , for example
@phax After trying to avoid to use the image usages (maybe will try this later), the IDE claims there are duplicate classes:
Duplicate class org.apache.commons.logging.Log found in modules commons-logging-1.2 (commons-logging:commons-logging:1.2) and jcl-over-slf4j-2.0.7 (org.slf4j:jcl-over-slf4j:2.0.7)
Duplicate class org.apache.commons.logging.LogConfigurationException found in modules commons-logging-1.2 (commons-logging:commons-logging:1.2) and jcl-over-slf4j-2.0.7 (org.slf4j:jcl-over-slf4j:2.0.7)
Duplicate class org.apache.commons.logging.LogFactory found in modules commons-logging-1.2 (commons-logging:commons-logging:1.2) and jcl-over-slf4j-2.0.7 (org.slf4j:jcl-over-slf4j:2.0.7)
Duplicate class org.apache.commons.logging.impl.NoOpLog found in modules commons-logging-1.2 (commons-logging:commons-logging:1.2) and jcl-over-slf4j-2.0.7 (org.slf4j:jcl-over-slf4j:2.0.7)
Duplicate class org.apache.commons.logging.impl.SimpleLog found in modules commons-logging-1.2 (commons-logging:commons-logging:1.2) and jcl-over-slf4j-2.0.7 (org.slf4j:jcl-over-slf4j:2.0.7)
How come?
Maybe because I use Kotlin too?
About org.apache.commons.logging.Log
and org.apache.commons.logging.LogFactory
, it says it's used in these:
Gradle: commons-logging:commons-logging:1.2
Gradle: org.slf4j:jcl-over-slf4j:2.0.7
org.apache.commons.logging.impl
org.jetbrains.kotlin.de.undercouch.gradle.tasks.download.org.apache.commons.logging
org.jetbrains.kotlin.de.undercouch.gradle.tasks.download.org.apache.commons.logging.impl
For org.apache.commons.logging.LogConfigurationException
, it says it's used in these:
Gradle: commons-logging:commons-logging:1.2
Gradle: org.slf4j:jcl-over-slf4j:2.0.7
org.jetbrains.kotlin.de.undercouch.gradle.tasks.download.org.apache.commons.logging
And for org.apache.commons.logging.impl.SimpleLog
and org.apache.commons.logging.impl.NoOpLog
:
Gradle: commons-logging:commons-logging:1.2
Gradle: org.slf4j:jcl-over-slf4j:2.0.7
org.jetbrains.kotlin.de.undercouch.gradle.tasks.download.org.apache.commons.logging.impl
Ah yes - both SLF4J
and commons-logging
are logging frameworks.
They both have separate artifacts for their API (slf4j-api
and commons-logging-api
).
But you must choose only one implementation. Either Log4J2, Logback, commons-logging, Java Util Logging etc.
I prefer using Log4J2
and org.slf4j:jcl-over-slf4j:2.0.7
as the implementation for the commons-logging-api
.
Your solution depends on the Kotlin default logging - I don't know it. Most likely you need to exclude either commons-logging:commons-logging:1.2
or org.slf4j:jcl-over-slf4j:2.0.7
@phax Do you know how to do such a thing in gradle kts ?
I never did such a thing.
I tried to follow the instructions and there are so many options. I don't get which I should use:
https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html
https://docs.gradle.org/current/userguide/resolution_rules.html
How did you get it to work? Maybe I can use what you did?
I use Maven - Maven has an explicit <exclude>
element to exclude a specific dependency - no idea how this is done in Gradle.
https://docs.gradle.org/current/userguide/dependency_downgrade_and_exclude.html#sec:excluding-transitive-deps seems like what you need
@phax Can you please copy-paste what you used in maven?
Maybe from this I can try to write in gradle-kts form.
I mean your own code (maven snippets), of which ones you've excluded.
I was looking, but couldn't find something in my dependencies - I am always very cautious with them, so usually there is no need to exclude stuff
Edit: for logging I am only including slf4j-api
in all dependencies. Only the resulting applications/web application include the logging framework itself. For testing purposes (e.g. in this library) I am including slf4j-simple
with scope test
to only have it available for testing. slf4j-simple
is like the simplest logging implementation: it writes everything to stdout only.
Odd that it works fine for you. Multiple modules with same classes and paths to them...
How does it get built...
Anyway, I will try...
Thank you
Ah, I see what you mean, because commons-logging
is referenced from pdfbox
and you want to use an SLF4J binding.
Therefore I suggest:
- Exclude
commons-logging:commons-logging:1.2
- Include
commons-logging:commons-logging-api:1.1
Looks weird, but guarantees that the API requirements of PDFBox are fulfilled, but no "implementation" is present
Shouldn't it be the opposite? 1.2 is newer...
The API is a subset and hasn't changed. Only some implementation specific parts have changed in the 1.2 implementation release. Se the different artifact IDs
OK so I tried this:
implementation("commons-logging:commons-logging-api:1.1"){
exclude("commons-logging:commons-logging:1.2")
}
And got even more duplicates for some reason:
And I tried this:
implementation("commons-logging:commons-logging-api:1.1"){
exclude(group = "commons-logging", module = "commons-logging")
}
And got even more duplicates for some reason:
I think they are identical.
:(
I meant
implementation("com.helger:ph-pdf-layout:7.3.0"){
exclude("commons-logging:commons-logging:1.2")
}
implementation("commons-logging:commons-logging-api:1.1")
or so - whatever the right syntax is
Still duplicates:
There is still some commons-logging:commons-logging:1.2
left - dunno from where. Maybe some other dependency also includes it. Can you ignbore the errors in this particular case? I think it's okay in this case
It prevents from building the app (no output APK file to install and run), so I can't ignore.
If you wish, I can put here the project after these changes.
Maybe you can post the full build file here, or send it by email
Remove implementation("org.apache.pdfbox:pdfbox:3.0.0")
and try again - that should be included automatically (transitively)
@phax It's commented (with //
) , so it doesn't affect it.
You are true.
What about the force("commons-logging:commons-logging:1.2")
on top
No idea - sorry. Check if you can list the transitive dependencies....
(Something like mvn tree:tree
)
Too bad