Comments (26)
Hi Harald,
Great! I will have a PR ready as soon as I have at least smoketested it on JFIF files.
The changes are on the branch linked to above, and are as I described in the first post (a config in in the parent, and referencing the maven-bundle-plugin in of each pom building a jar file), if you wish to inspect them.
I'm trying to leave as much to maven-bundle-plugin defaults as possible.
Re: package conflicts: Noted! I will notify you about any such conflicts I see.
from twelvemonkeys.
I made a fork of TwelweMonkeys and made a push of a fix to a branch.
But I haven't made a PR yet.
I will see if I can make it work first.
It may be that I have to adjust some imports and exports manually, and there may be issues with multiple jars/bundles exporting the same package. I haven't checked yet. If it is multiple jars/bundles exporting the same package, then fatjar'ing is the only way to go (other than moving packages).
from twelvemonkeys.
We use Twelve monkeys in Lucee, it required a bit of plumbing
https://luceeserver.atlassian.net/browse/LDEV-3961
and re-wrapping the all bundles
https://github.com/orgs/lucee/repositories?language=&q=twelvemonkeys&sort=&type=all
from twelvemonkeys.
Status update:
- Just adding the OSGi headers for export and import of packages wasn't enough. I also need to add Require-Capability and Provide-Capability MANIFEST.MF headers to all jar files implementing IMageIO SPI plugins
- Luckily I think it will be possible to add this in the of imageio/pom.xml (right now I just have it for testing in the imageio-jpeg jar), which should minimize the config clutter, because I think it will be the same headers for all ImageIO plugins
- I've run into a problem during testing because Apache Aries SPI Fly, which implements the mediation between SPI and OSGi for some reason has decided that one of my beans and the JDBC ResultSet are supposed to be unified and fails because they don't have a common superclass. I think this is a bug in SPI Fly, and I will be debugging to see what in my code tickles the bug and what I can do to work around it. https://issues.apache.org/jira/browse/ARIES-2110 (but it has slowed down me testing what I was supposed to test, which is the Provide-Capability headers for the twelvemonkeys imageio plugins)
- I ran into another weird thing today, which was that what worked yesterday did not work today. I figured out what it was: maven downloads new twelvemonkeys snapshots from wherever they are deployed. So to get things working with OSGi I have to make sure that I have a local snapshot build that is newer than the downloaded one. Not a big problem but it had me scratching my head for a while until I decided to look at the MANIFEST.MF of the snapshot in ~/.m2/repository/
So there is progress, but slow progress.
from twelvemonkeys.
I had a lightning speach on JavaZone, but now that is over, I have started looking into this again.
Current status:
- I have created a fork of TwelveMonkeys and created a branch with my changes
- I have made a test-application with a rudimentary react GUI that uploads the URL of a JPEG file and then returns metadata for the image (the comment, if any, is extracted using imageio). The master branch currently uses the built-in imageio
- Instructions for how to build and run the test application can be found in the README
- I have created a branch on the test-application where I am trying to use Apache Aries SPI-fly to inject TwelveMonkeys into the imageio inside OSGi (so far without luck, still using com.sun.imageio.plugins.jpeg.JPEGImageReader according to the remote debug)
from twelvemonkeys.
Note: If there is a change of the PR being accepted I can create a PR for it.
I'm talking about the minimal approach here: just making the jar files OSGi bundles
from twelvemonkeys.
Hi Steinar,
Thanks for looking into this!
I don't use OSGi for anything, and won't be able to verify it's correctness, but as long as we don't destroy the normal SPI registration (which is, for better or worse, the way ImageIO plugins are registered) and other functionality of the plugins, I think I can accept a PR for this.
The centralized registry/SPI approach isn't great for normal WAR/EAR container deployment either, but at least it can be worked around using the context listener approach. I wish there was a better way...
I don't think there should be multiple JARs containing the same package (with possible exception of the test-JARs), as that causes issues with normal Java modules as well. If you find any issues related to this, let me know, and I'll help restructure the code if needed.
from twelvemonkeys.
(it's the rewrapping I'm hoping to avoid by making the jars be bundles in the first place).
If you know OSGi stuff I'll appreciate you taking a look at the branch I've made.
It's pretty simple: a low energy approach using defaults as much as possible (it's my standard maven-bundle-plugin config lifted over).
from twelvemonkeys.
I know enough about OSGI to understand it, but that's about it
um, which branch do you mean? I see a lot of links but none seem to be a branch?
from twelvemonkeys.
I thought the branch showed up here, but it was just the single commit: steinarb@daa9ef8 (it is just a single commit)
from twelvemonkeys.
I had a lightning speach on JavaZone
I was there, but missed it, sorry... π€·π»
But now I know slightly more about IPv6 than I did before... π
I just skimmed the SPI-Fly docs, and it seems it should work for this use case.
from twelvemonkeys.
Yes, SPI-Fly should work. I think it is just an issue of finding the right services to provide and require.
Now that I have the minimal test application this should be easier to do.
(Saw your co-presented talk at JavaZone a while back (was it before the pandemic?), that's how I knew about TwelveMonkeys)
from twelvemonkeys.
Now I'm a bit further:
- I switched spifly logging in apache karaf from the default WARN to INFO
- I published javax.imageio.spi.ImageReaderSpi from the MANIFEST.MF of imageio-jpeg
Provide-Capability: osgi.serviceloader;osgi.serviceloader="javax.imageio .spi.ImageReaderSpi"
- I imported all javax.imageio.spi.ImageReaderSpi services in the MANIFEST.MF of twelvemonkeys-karaf-demo
Require-Capability: osgi.extender;filter:="(osgi.extender=osgi.servicelo ader.processor)",osgi.service;filter:="(objectClass=no.priv.bang.demos. frontendkarafdemo.ImageService)";effective:=active,osgi.service;filter: ="(objectClass=org.osgi.service.log.LogService)";effective:=active,osgi .serviceloader;filter:="(osgi.serviceloader=javax.imageio.spi.ImageRead erSpi)";cardinality:=multiple,osgi.extender;filter:="(&(osgi.extender=o sgi.component)(version>=1.5.0)(!(version>=2.0.0)))",osgi.implementation ;filter:="(&(osgi.implementation=osgi.http)(version>=1.1.0)(!(version>= 2.0.0)))",osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=17))"
- According to the karaf.log, the twelvemonkeys imageio-jpeg was found and registered with imageio
2023-09-16T16:29:42,032 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi of service javax.imageio.spi.ImageReaderSpi in bundle com.twelvemonkeys.imageio.jpeg 2023-09-16T16:29:42,033 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | no.priv.bang.servlet.frontend/1.6.8 2023-09-16T16:29:42,035 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.twelvemonkeys.imageio.tiff/3.10.0.SNAPSHOT
- Nevertheless, the com.sun.imageio.plugins.jpeg.JPEGImageReader was used (in this code)
2023-09-16T16:35:20,357 | INFO | qtp2023681064-374 | ImageServiceProvider | 82 - no.priv.bang.demos.twelvemonkeys-karaf-demo - 2.0.0.SNAPSHOT | reader class: com.sun.imageio.plugins.jpeg.JPEGImageReader
Tips to where to go from here is appreciated.
Do I need to export all services for one of them to work?
Do I need to export both readers and writers?
Do I need some more dependencies?
Have I picked the wrong JPEG plugin to export a service from? (I planned to just start with one and see what I got, but I may have picked the wrong one? Would be nice to get feedback from someone that knows imageio and twelvemonkeys)
from twelvemonkeys.
Now I've done osgi.serviceloader exports for all OSGi bundles in the imageio directory (I've exported the services found in the META-INF/services directories).
According to the logs spifly picks up and includes services.
But my example code still gets com.sun.imageio.plugins.jpeg.JPEGImageReader instead of com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi
Is there something wrong/missing in the way my example code accesses imageio?
Have I forgotten any magic invocations for spifly?
What I am doing is adding maven dependencies and add a Require-Capability for javax.imageio.spi.ImageReaderSpi (which is satisfied, because otherwise the app wouldn't have loaded).
Do I need to do something beyond this?
Here are the karaf.log messages from the spifly registration of the SPI services:
2023-09-17T19:30:20,712 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.twelvemonkeys.imageio.core/3.10.0.SNAPSHOT
2023-09-17T19:30:20,716 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.stream.BufferedFileImageInputStreamSpi of service javax.imageio.spi.ImageInputStreamSpi in bundle com.twelvemonkeys.imageio.core
2023-09-17T19:30:20,718 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.stream.BufferedRAFImageInputStreamSpi of service javax.imageio.spi.ImageInputStreamSpi in bundle com.twelvemonkeys.imageio.core
2023-09-17T19:30:20,720 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.stream.BufferedInputStreamImageInputStreamSpi of service javax.imageio.spi.ImageInputStreamSpi in bundle com.twelvemonkeys.imageio.core
2023-09-17T19:30:20,722 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.color.ProfileDeferralActivator$Spi of service javax.imageio.spi.ImageInputStreamSpi in bundle com.twelvemonkeys.imageio.core
2023-09-17T19:30:20,723 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.twelvemonkeys.imageio.psd/3.10.0.SNAPSHOT
2023-09-17T19:30:20,726 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.plugins.psd.PSDImageReaderSpi of service javax.imageio.spi.ImageReaderSpi in bundle com.twelvemonkeys.imageio.psd
2023-09-17T19:30:20,727 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.twelvemonkeys.imageio.metadata/3.10.0.SNAPSHOT
2023-09-17T19:30:20,729 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.fasterxml.jackson.core.jackson-annotations/2.15.2
2023-09-17T19:30:20,731 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.fasterxml.jackson.core.jackson-core/2.15.2
2023-09-17T19:30:20,732 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.fasterxml.jackson.core.jackson-databind/2.15.2
2023-09-17T19:30:20,734 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.twelvemonkeys.imageio.tiff/3.10.0.SNAPSHOT
2023-09-17T19:30:20,737 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.plugins.tiff.TIFFImageReaderSpi of service javax.imageio.spi.ImageReaderSpi in bundle com.twelvemonkeys.imageio.tiff
2023-09-17T19:30:20,738 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.plugins.tiff.BigTIFFImageReaderSpi of service javax.imageio.spi.ImageReaderSpi in bundle com.twelvemonkeys.imageio.tiff
2023-09-17T19:30:20,739 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | org.apache.commons.lang3/3.12.0
2023-09-17T19:30:20,741 | INFO | features-3-thread-1 | FeaturesServiceImpl | 19 - org.apache.karaf.features.core - 4.4.3 | com.twelvemonkeys.imageio.jpeg/3.10.0.SNAPSHOT
2023-09-17T19:30:20,744 | INFO | features-3-thread-1 | BaseActivator | 87 - org.apache.aries.spifly.dynamic.bundle - 1.3.4 | Registered provider com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi of service javax.imageio.spi.ImageReaderSpi in bundle com.twelvemonkeys.imageio.jpeg
from twelvemonkeys.
Your use of ImageIO seems fine. It's strongly recommended to dispose()
of the ImageReader
in a finally
block to not leak resources, but that won't affect OSGi lookup/registering.
I'm not exactly sure what Registered provider com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReaderSpi of service javax.imageio.spi.ImageReaderSpi in bundle com.twelvemonkeys.imageio.jpeg
means in this context. Based on the symptoms, it doesn't seem to be that the SPI is registered in the IIOServiceRegistry
. Are you able to attach a debugger while running this code? If so, can you put a break point in the JPEGImageReaderSpi.onRegistration
method and see if it's hit at all? And if it is, is the delegate provider found and the ordering set correctly?
Another thing to check, if debugging isn't possible, is to loop through your readers
iterator in the above linked code, to print the names of all possible JPEG capable ImageReaders
. If you only have the built-in, then the problem is still that the SPIs are not correctly registered. If the TwelveMonkeys one is there, but ordered after the built-in, then there's an issue with the ordering I would need to look further into.
Have you tried another format like PSD, where there is no built-in plugin? Does that work?
It's a bit hard to remote-debug based on log files, especially as I'm no OSGi guy... Maybe we should just meet up and fix this some day, if you are in Oslo? π
from twelvemonkeys.
Ok, I didn't have debugging into the java runtime library initially so I tried the second approach first: iterate over all readers. I basically just made the first "if (readers.hasNext)" into a while.
And if the logs are to be trusted, there is only one reader in readers (second iteration would probably crash the way I made it, attempting to consume the inputStream a second time, but that didn't happen either, and debugging the while loop also told me a single iteration through readers).
I had already installed openjdk-17-dbg without getting debug. Now I installed openjdk-17-source and that immediately gave me debugging into the java runtime library.
So I put a breakpoint in JPEGImageReaderSpi.onRegistration and that was never trigged.
So the conclusion from both debug approaches, is that the SPIs are not correctly registered.
It was good to get that clarified because then I won't have to go down many wrong paths or assumptions. π
My plan for now is to try to read up more on spifly to see if there is something I've forgotten to do. I'll look into work someone did earlier in a rebundled Twelvemonkeys (they got it working, but I think maybe they fatjar'd it...?).
Yes, I'm in Oslo so it would be possible to meet up and debug. Not sure where or when, and probably not during this week or the weekend.
from twelvemonkeys.
Thanks, that gives a slightly clearer view of the issue. ππ»
You could of course try to invoke
// Registers all locally available IIO plugins.
ImageIO.scanForPlugins();
once, after the SpiFly registration is done, if you have something you can hook onto, as it doesn't seem that SpiFly is registering the Spis with the IIORegistry
(not sure if this is intentional or a misconfiguration though). And see if that helps get the Spis registered. This is not something I generally recommend (as you might have issues when/after unloading your OSGi bundles later), but it might help us pinpoint the problem.
from twelvemonkeys.
Since I don't have a component expecting injection of a service from the TwelveMonkeys bundles I don't have anything that I can expect to be run after the registration (the @activate method of a component will be run after all injected services are in place).
But what I can do, in my test application, is to create a rest endpoint that does the scan and create a"scan for imageio plugins" button in the GUI to do the scan (it is a test application after all).
from twelvemonkeys.
I have added a REST endpoint to do ImageIO.scanForPlugins() and a react button to trigger the REST endpoint, to a branch in the test program https://github.com/steinarb/twelvemonkeys-karaf-demo/tree/use-twelvemonkeys-imageio
But both the rescan function and the actual metadata query only finds com.sun.imageio.plugins.jpeg.JPEGImageReader (and I'm not surprised when looking at the code of ImageIO.scanForPlugins(), because scanning a classpath that way doesn't work well in OSGi).
(Note that the unit test returns both JPEG readers, but that doesn't help us any)
But I'm not giving up yet. I will study all spifly docs and examples I can find.
I found this yesterday: https://github.com/Maurice-Betzel/twelvemonkeys-osgi
It uses the rebundle-into-fatjar approach, but I don't know if that's important (but it would actually make ImageIO.scanForPlugins() work, I think...?).
I added the SPI-Provider and SPI-Consumer MANIFEST.MF headers, but they didn't make any difference that I could see.
SPI-Provider and SPI-Consumer are Spifly-specific.
Ah! Interesting bit here: "Additionally services found in META-INF/services are registered in the OSGi Service Registry."
That means it should be possible to inject all of the SPI services into an OSGi component and register them manually (if everything else fails).
from twelvemonkeys.
Success! I added an OSGi DS component, that listens for the OSGi services created from SPI Services by Apache Aries Spifly, and registers the services with the imageio service registry:`
@Component
public class ImageioSpiRegistration {
@Reference(cardinality = ReferenceCardinality.MULTIPLE)
public void registerImageReaderSpi(ImageReaderSpi readerProvider) {
IIORegistry.getDefaultInstance().registerServiceProvider(readerProvider);
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE)
public void registerImageWriterSpi(ImageWriterSpi writerProvider) {
IIORegistry.getDefaultInstance().registerServiceProvider(writerProvider);
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE)
public void registerImageInputStreamSpi(ImageInputStream inputStreamProvider) {
IIORegistry.getDefaultInstance().registerServiceProvider(inputStreamProvider);
}
}
Adding this component to the OSGi runtime, makes imageio, called from a different OSGi component, pick com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader to read a JPEG (JFIF) file.
I tried using the Spifly-specific SPI-Consumer MANIFEST.MF header to call IIORegistry.getDefaultInstance().registerServiceProvider() but that didn't work.
I used the MANIFEST.MF header:
SPI-Consumer: javax.imageio.spi.IIORegistry#getDefaultInstance#registerServiceProvider
but I don't think Spifly is able to handle two chained method calls.
I think that if there had been a static registration method using this approach would have worked.
But using a dedicated OSGi component will work on other SPI service loaders than Aries spifly.
from twelvemonkeys.
Added a PR for the change, with an explanation of the changes done to the pom files.
No changes to any code, only changes to pom files and only changes to the MANIFEST.MF of the files that will not affect non-OSGi applications.
from twelvemonkeys.
And if/when the above PR is accepted, if it is of interest I could create a different PR for an Twelvemonkeys/osgi-registrar module that will contain the above DS component that registers the Twelvemonkeys services with imageio and a README.md explaining how to use it from apache karaf.
from twelvemonkeys.
I don't use OSGi for anything, and won't be able to verify it's correctness
I donβt either and know very little, but was comforted by using pax-exam tests as a sanity check in my oss project (example).
from twelvemonkeys.
I don't use OSGi for anything, and won't be able to verify it's correctness
I donβt either and know very little, but was comforted by using pax-exam tests as a sanity check in my oss project (example).
Ah! Pax exam tests I can do (if of interest)! π
I even provided a pax exam test to the PosgreSQL JDBC build after creating a karaf feature (and possibly also a DataSourceProvider...? I can't remember it's been a while).
But as to where the adapter I've made that takes Twelvemonkey SPI services turned into OSGi services by Apache Aries Spifly, and registers them with the ImageIO ServiceRegistry should live: there is no need for it to live in Twelvemonkeys.
I could just create a standalone project imageio-spi-registrar-osgi-adapter (or something) and release it to maven central.
from twelvemonkeys.
But just stating for the record, so that there is no confusion: neither a pax exam unit test and/or the OSGi component I used to register services with the ImageIO service registry, are a requirement to accept the current PR.
The current PR will not affect non-OSGi applications in any way. The changes in the MR just add headers to the MANIFEST.MF of the jars. Headers that are not used by non-OSGi applications.
The result of the current MR has been tested by me in that it loads the imageio OSGi bundles in apache karaf and an application using imageio to read JPEG/JFIF metadata uses the Twelvemonkeys JPEG image reader to read the image.
from twelvemonkeys.
Nice! Thanks!
from twelvemonkeys.
Related Issues (20)
- Some malformed PSD images never return from `ImageIO.read()` using 3.10.0 HOT 2
- WebP: Images decoded with yellow tint HOT 1
- Possible bug in Half.shortBitsToFloat HOT 5
- Troubleshooting with ImageIO plugin registry issue (NoClassDefFoundErrors) without web.xml file HOT 1
- YCCK JPEG from a PDF with wrong colors HOT 5
- TIFF: Support SAMPLEFORMAT_COMPLEXINT (5) HOT 3
- WebP plugin stops working when other plugins are enabled too HOT 2
- PSD: Get layer kind (type) to metadata HOT 1
- Twelvemonkeys Servlet should support Jakarta HOT 6
- JPEGImageReader read invalid image without throwing exception HOT 4
- PSD: When make PNG from PSD using TwelveMonkeys, it's different from Photoshop. HOT 4
- Change Maven GPG plugin to use Bouncy Castle signer
- Unsupported BitsPerSample for SampleFormat 3/Floating Point (expected 16/32): 64 HOT 4
- PSD: BufferOverflowException if encoder adds garbage to the end of rows
- Dynamic images in WebP format, and even ordinary GIF images, cannot read delays after using this plugin. HOT 2
- Warning system custom messages HOT 3
- Unable to read dynamic webp using javax.imageio.ImageIO#read(java.io.InputStream) on aws lambda HOT 1
- TIFF: ArrayIndexOutOfBoundsException in HorizontalDeDifferencingFloatingPointStream.decodeDeltaBytes HOT 3
- JPEG 2000 format support HOT 1
- TIFF: Decoding chunky gray + extra samples is broken HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from twelvemonkeys.