Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Newcomers » Newcomers » Tycho + Target Platform + ServiceLoader(Tycho + Target Platform + ServiceLoader)
Tycho + Target Platform + ServiceLoader [message #1842623] Fri, 25 June 2021 16:21 Go to next message
Anthony Nillar is currently offline Anthony NillarFriend
Messages: 77
Registered: May 2014
Member
Hi all,

I was trying to use this new feature of adding a maven dependency using a target platform [1]. In this sense, I added Roaster API [2] in my Eclipse plug-in using exactly the dependencies that they described. Then, when I use this plug-in I am getting this error.

 No instances of [org.jboss.forge.roaster.spi.JavaParser] were found on the classpath.


This error arises in this line of code:

ServiceLoader.load(JavaParser.class, Roaster.class.getClassLoader())


I really do not know why this class is not loaded because is it declared in Meta-Inf/services [3].

Eclipse: 2020-09
Maven: 1.18

I really do not know how to solve this issue. I do not know if this is related to this [4]. However, I tried the solution number 2 but with no luck.

I don't know what I'm missing, Any hints?

If this is not related to this group, please let me know where I should post this.

Thanks in advance!

Kind regards,
Antonio

[1] https://läubisoft.gmbh/en/articles/using-maven-artifacts-in-pde-rcp-and-tycho-builds/
[2] https://github.com/forge/roaster
[3] https://github.com/forge/roaster/blob/master/impl/src/main/resources/META-INF/services/org.jboss.forge.roaster.spi.JavaParser
[4] http://blog.vogella.com/2021/03/08/eclipse-rcp-java-11-jaxb/
Re: Tycho + Target Platform + ServiceLoader [message #1842627 is a reply to message #1842623] Fri, 25 June 2021 16:46 Go to previous messageGo to next message
Thomas Wolf is currently offline Thomas WolfFriend
Messages: 395
Registered: August 2016
Senior Member
Anthony Nillar wrote on Fri, 25 June 2021 16:21
I added Roaster API [2] in my Eclipse plug-in


ServiceLoader may not work as expected in an OSGi environment. Possibly you need an OSGi ServiceLoader Mediator like SPI Fly from Apache Aries.
Re: Tycho + Target Platform + ServiceLoader [message #1842674 is a reply to message #1842627] Mon, 28 June 2021 12:36 Go to previous messageGo to next message
Anthony Nillar is currently offline Anthony NillarFriend
Messages: 77
Registered: May 2014
Member
Hi Thomas,

Thanks for the quick reply!

Indeed, in an OSGI environment the ServiceLoader is not working as expected. Besides your suggestions, I also take a look at this blog entry [1].

Despite my efforts, it has been not possible to make it work.

Provider: Since I add the jar using the target platform (plugin at.jku.se.monitoring.target)I use the edit instructions in order to add the required capability and the provide-capability. Then, the location looks like this:

<location includeDependencyScope="runtime" includeSource="true" missingManifest="generate" type="Maven">
			<groupId>org.jboss.forge.roaster</groupId>
			<artifactId>roaster-jdt</artifactId>
			<version>2.23.0.Final</version>
			<type>jar</type>
			<instructions><![CDATA[
Bundle-Name:           Bundle derived from maven artifact ${mvnGroupId}:${mvnArtifactId}:${mvnVersion}
version:               ${version_cleanup;${mvnVersion}}
Bundle-SymbolicName:   wrapped.${mvnGroupId}.${mvnArtifactId}
Bundle-Version:        ${version}
Import-Package:        *;resolution:=optional
Export-Package:        *;version="${version}";-noimport:=true
DynamicImport-Package: *
Require-Capability: osgi.extender; 
 filter:="(osgi.extender=osgi.serviceloader.registrar)"
Provide-Capability: osgi.serviceloader;
 osgi.serviceloader=org.jboss.forge.roaster.spi.JavaParser
]]></instructions>
		</location>


Is this correct?

Consumer: In my consumer plugin (test.roaster) I added the require capability like this:

Require-Capability: osgi.extender;
 filter:="(osgi.extender=osgi.serviceloader.processor)",
 osgi.serviceloader;
 filter:="(osgi.serviceloader=org.jboss.forge.roaster.spi.JavaParser)";
 cardinality:=multiple


Is this correct?

In the main package, I created a Junit class to test this and this error arises.

index.php/fa/40700/0/

Am I missing something? I uploaded the minimal example so you can take a look if you have the time to do so (test-roaster.zip).

Thanks in advance!

Kind regards,
Antonio

[1] https://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html
Re: Tycho + Target Platform + ServiceLoader [message #1842706 is a reply to message #1842674] Tue, 29 June 2021 12:15 Go to previous messageGo to next message
Thomas Wolf is currently offline Thomas WolfFriend
Messages: 395
Registered: August 2016
Senior Member
I don't know. I have never used roaster (which seems to encapsulate Eclipse JDT), nor SPI Fly. Some things I noticed:

  1. You have the SPI consumer Require-Capability on your test.roaster project. But isn't the real SPI consumer roaster-api? That's where the ServiceLoader.load() calls are.
  2. The instructions in the target platform appear to be sensitive to line-breaks. Put the capabilities on one line. And double check the generated MANIFEST.MF in the Eclipse package explorer, where the roaster jars appear under Plug-In Dependencies.
  3. I don't understand why you prefix the bundle name with "wrapped.". That doesn't seem to be necessary?
  4. The dynamic weaving SPI fly bundle needs to have a lower start level than the bundles that shall be woven.
  5. roaster-jdt appears to contain a shaded Equinox. Possibly that doesn't interact well with the real Equinox used to run the test?
  6. Package org.jboss.forge.roaster.spi is a split package between roaster-api and roaster-jdt. Perhaps that causes problems?

I did play around with this, and fixing points 1 - 4 indeed gives something that validates and that can start. It then fails at run-time with
java.lang.IllegalStateException: No instances of [org.jboss.forge.roaster.spi.JavaParser] were found on the classpath.
	at org.jboss.forge.roaster.Roaster.getParsers(Roaster.java:55)
	at org.jboss.forge.roaster.Roaster.create(Roaster.java:94)
	at test.roaster.TestJavaParser.test(TestJavaParser.java:13)

Debugging the test shows that inside Roaster.create(), the classloader indeed is an EquinoxClassLoader with only the classes from the roaster-api bundle.

Not sure what to do about points 5 and 6.
Re: Tycho + Target Platform + ServiceLoader [message #1842710 is a reply to message #1842706] Tue, 29 June 2021 12:49 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 31957
Registered: July 2009
Senior Member
Perhaps something here would help:

https://wiki.eclipse.org/Context_Class_Loader_Enhancements#Buddy_Class_Loading

E.g., I do this in EMF's Ecore plug-in's MANIFEST.MF so that Class.forName can find names in dependent bundles:

Eclipse-BuddyPolicy: dependent


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Tycho + Target Platform + ServiceLoader [message #1842719 is a reply to message #1842710] Tue, 29 June 2021 14:14 Go to previous messageGo to next message
Thomas Wolf is currently offline Thomas WolfFriend
Messages: 395
Registered: August 2016
Senior Member
Actually, it seems to be a problem with that JUnit test. The JUnit launcher does its own things relating to class loaders and starting the framework.

If I add a proper bundle activator that does exactly the same as that test method when started; it works when I just launch an OSGi platform with all the necessary bundles.

See the attachment; it's the original test-roaster.zip with all my fixes. RunJavaParserOsgi is a simple launch config to run a minimal OSGi platform; output is on stdout and should appear in the Eclipse console. It should print the generated class source.

Interestingly this launch config even works with the start level for the spifly dynamic weaving bundle left at "default".
  • Attachment: Example.zip
    (Size: 7.40KB, Downloaded 14 times)
Re: Tycho + Target Platform + ServiceLoader [message #1842981 is a reply to message #1842719] Thu, 08 July 2021 14:05 Go to previous messageGo to next message
Anthony Nillar is currently offline Anthony NillarFriend
Messages: 77
Registered: May 2014
Member
Hi Thomas and Ed,

Thank you so much for taking the time and help me with this. Indeed, I was confused with the consumer and provider concept.

Based on the example that @Thomas uploaded I was able to mimic this on my application. However, I have to change the start level and autostart of apache aries and jboss like this:

index.php/fa/40740/0/

The thing is that I am implementing a plug-in for Eclipse. Therefore, I was wondering how to programmatically do this so that it works for users when they installed the plugin. Should I activate programmatically aries and jboss somehow? What should be the best approach?

Thanks!

Kind regards,
Antonio
Re: Tycho + Target Platform + ServiceLoader [message #1842988 is a reply to message #1842981] Thu, 08 July 2021 17:09 Go to previous message
Thomas Wolf is currently offline Thomas WolfFriend
Messages: 395
Registered: August 2016
Senior Member
Never had to do this. This old post says it's possible (for Equinox) via p2.inf. At least it once was; not sure this still works. I don't think this is standard.

BTW: interesting that you have to start the jboss bundles first. The SPIFly documentation says SPIFly should be started first?
Previous Topic:Which version did I install?
Next Topic:Open declaration is not working in feature files
Goto Forum:
  


Current Time: Sun Jul 25 04:05:09 GMT 2021

Powered by FUDForum. Page generated in 0.08648 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top