Eclipse PDE : Programmatically read the contents of the target platform - java

In my application, the target platform is set to contain some of my custom plugins apart from the eclipse plugins. During the application's usage, I want to check the contents of the target platform against an installed folder which is supposed to contain my custom plugins.
Effectively, I would like to get a list of all the bundles in the target platform (Eclipse plugins + my custom plugins).
I have tried using getBundleContext() in both ResourcesPlugin and PDEPlugin but that returns only the eclipse bas plugins and not my custom plugins.

ITargetPlatformService service = PDECore.getDefault().acquireService(ITargetPlatformService.class);
for (TargetBundle targetBundle: service.getWorkspaceTargetDefinition().getBundles()) {
//then get name of plugin via targetBundle.getBundleInfo().getSymbolicName()
}
The problem with this code is that you get a warning similar to:
Discouraged access: The type 'PDECore' is not API (restriction on required library '...\eclipse-rcp-photon-R-win32-x86_64\plugins\org.eclipse.pde.core_3.12.0.v20180516-1159.jar')

Related

How to configure my plugin for working both with IntelliJ and Android Studio

I'm (almost) a beginner in plugin creation (I created one a long time ago) and I would like to create a plugin that works BOTH with IntelliJ and with Android Studio (this to start with, because later I would like it to work also for Webstorm, PyCharm...).
The principle of my plugin is to use the parsing provided by IntelliJ (for Java for the moment, later for Kotlin, PHP...) thanks to the PSI (I MUST use PSI!). I've spent days reading and testing information at https://plugins.jetbrains.com/docs/intellij , https://plugins.jetbrains.com/docs/intellij/android-studio.html (and so on) and online tutorials, but I still can't configure my project (even before coding it).
Can you help me?
Here are some information:
I created the plugin ('empty' plugin for now) from the github template presented the online documentation. No problem for that.
I use a JDK 11. I guess this is what I have to do now (unlike before when I had to use the IntelliJ JDK).
I want to code my plugin in Java (not in Kotlin). The template generated Kotlin code (MyBundle.kt, listeners, services...) but I don’t need these Kotlin files. What to write to replace this code in Java ?
I don't know Kotlin (or very very little) and I usually develop in Java with Android Studio and Gradlen and I want to keep the build.gradle.kst (better than build.gradle).
I must also use a personal .jar file (not a lib like JSON for instance) for my plugin to work. Do I only have to add this jar in the libraries of the 'project settings' or do I have to do something else?
Here is my current configuration (most interesting parts):
plugin.xml (with error)
<depends>com.intellij.modules.lang</depends>
<depends>com.intellij.modules.java-capable</depends> // correct ?
<depends>com.intellij.modules.androidstudio</depends> // error : cannot resolve plugin in dependencies
<depends>org.jetbrains.android</depends> // error : cannot resolve plugin in dependencies
build.gradle.kts (with questions)
plugins {
// Java support
id("java")
// Gradle IntelliJ Plugin
id("org.jetbrains.intellij") version "1.4.0"
// Gradle Changelog Plugin
id("org.jetbrains.changelog") version "1.3.1"
// Gradle Qodana Plugin
id("org.jetbrains.qodana") version "0.1.13"
}
...
configurations {
create("externalLibs")
}
dependencies {
// to integrate my personal jar file , correct ?
"externalLibs"(files("lib/myfile.jar"))
// to integrate an external API , correct ?
implementation("com.foo.api-java-sdk:1.0.2")
}
gradle.properties (with questions)
# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
pluginSinceBuild = 211
pluginUntilBuild = 213.*
# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IC
#platformVersion = 2021.1.3
platformVersion = 211.7628.21 // to be compatible between IJ and Android Studio, OK ?
# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins = com.intellij.java, org.jetbrains.android // is it correct ????
# Java language level used to compile sources and to generate the files for - Java 11 is required since 2020.3
javaVersion = 11
# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 7.4
If someone could give me the right configuration for all these files, it would be fine because I am totally lost and hopeless :-(
Thank you.

PsiClass to java.lang.Class

I'm developing plugin for IntelliJ IDEA. How can plugin get the name and version of libraries that are imported to the project that is being checked by plugin? I have PsiClass of the project, but cannot convert it to java.lang.Class. Maybe there's the way to get ClassLoader from PsiElement?
super.visitImportStatement(psiImport);
Class importedClass = Class.forName(psiImport.getQualifiedName(), true, psiImport.getClass().getClassLoader());
PsiImport.getClass().GetClassLoader() - returns ClassLoader of class PsiImportStatementImpl instead of ClassLoader of class that I've imported.
IntelliJ does mostly static analysis on your code. In fact, the IDE and the projects you run/debug have completely different classpaths. When you open a project, your dependencies are not added to the IDE classpath. Instead, the IDE will index the JARs, meaning it will automatically discover all the declarations (classes, methods, interfaces etc) and save them for later in a cache.
When you write code in your editor, the static analysis tool will leverage the contents of this index to validate your code and show errors when you're trying to use unknown definitions for example.
On the other hand, when you run a Main class from your project, it will spawn a new java process that has its own classpath. This classpath will likely contain every dependency declared in your module.
Knowing this, you should now understand why you can't "transform" a PsiClass to a corresponding Class.
Back to your original question:
How can plugin get the name and version of libraries that are imported to the project that is being checked by plugin?
You don't need to access Class objects for this. Instead, you can use IntelliJ SDK libraries. Here's an example:
Module mod = ModuleUtil.findModuleForFile(virtualFile,myProject);
ModuleRootManager.getInstance(mod).orderEntries().forEachLibrary(library -> {
// do your thing here with `library`
return true;
});

Add library to Eclipse plugin

In my Eclipse Plugin I have a table that shows Integer and String values. To edit the String values I'm using a TextCellEditor which is in the package org.eclipse.jface.viewers.
I have found a NumberCellEditor which I want to try. It is in the package org.eclipse.ve.internal.propertysheet.NumberCellEditor.
I cannot see this package in eclipse it is not listed in the plugin.xml file under Dependencies. It's not in the list that shows up when clicking the "Add"-Button either.
How can I use this class?
org.eclipse.ve appears to be the old Eclipse Visual Editor plugin which is no longer available.
Additionally classes in a package with internal in the name are off-limits (see Eclipse API Rules of Engagement). They may be changed or removed at any time.

Using jackson-dataformat-xml on android

I'm strugling with using jackson-dataformat-xml on android
I have some very basic code that works fine on oracle jre
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);
First I tried official documentation adapted for gradle (by me, not sure if done correctly):
compile 'com.fasterxml.jackson.core:jackson-core:2.5.4'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.5.4'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.4'
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.5.4'
compile 'org.codehaus.woodstox:woodstox-core-asl:4.4.1'
compile 'javax.xml.stream:stax-api:1.0-2'
Result: gradle fails build time about bundling corelibraries into an application
...
:app:preDexDebug
trouble processing "javax/xml/stream/EventFilter.class":
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
...
2nd attempt trying to follow Sean's answer
(Basicly he repackages corelibs with prefix names and rebuilds jackson-dataformat-xml to use the prefixed names)
compile 'com.fasterxml.jackson.core:jackson-core:2.1.2'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.1.2'
compile 'com.fasterxml.jackson.core:jackson-databind:2.1.2'
// Repackaged XML-specific libraries
compile 'edu.usf.cutr.android.xml:jackson-dataformat-xml-android:2.1.2'
compile 'edu.usf.cutr.android.xml:stax2-api-android:3.1.1'
compile 'edu.usf.cutr.android.xml:stax-api-android:1.0-2'
compile 'edu.usf.cutr.android.xml:aalto-xml-android:0.9.8'
And build time failed on duplicates
Duplicate files copied in APK META-INF/services/com.fasterxml.jackson.core.ObjectCodec
so added:
packagingOptions {
...
exclude 'META-INF/services/com.fasterxml.jackson.core.JsonFactory'
exclude 'META-INF/services/com.fasterxml.jackson.core.ObjectCodec'
}
When adding the exclusions it builds and deploys, but fails runtime on below stackdump (AFAIK it cant find the SAX provider, even tho it is added to the classpath to my understanding)
edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found
at edu.usf.cutr.javax.xml.stream.FactoryFinder.newInstance(FactoryFinder.java:72)
at edu.usf.cutr.javax.xml.stream.FactoryFinder.find(FactoryFinder.java:176)
at edu.usf.cutr.javax.xml.stream.FactoryFinder.find(FactoryFinder.java:92)
at edu.usf.cutr.javax.xml.stream.XMLInputFactory.newInstance(XMLInputFactory.java:136)
at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:97)
at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:85)
at com.fasterxml.jackson.dataformat.xml.XmlFactory.<init>(XmlFactory.java:82)
at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:46)
What is the proper way to move forward on either #1 or #2?
Number 2 is the correct approach (Android doesn't like it when you include classes in the official Java package namespace - but then again, I wrote the original answer so I'm biased ;) ).
I believe the FactoryConfigurationError: Provider com.bea.xml.stream.MXParserFactory not found error is due to a bug in the Android build tools. In previous versions of ADT for Eclipse and Gradle plugin < 0.7.0 the /META-INF/* files are stripped from the JARs during the build process. It seems like >= v0.7.0 shouldn't have the problem according to Google, but from others' reports it sounds like it still may be problematic, and could potentially remove the META-INF/services/javax.xml.stream.XMLInputFactory file, which is required for the platform to register Aalto.
Try the workaround mentioned in AOSP issue 59658 comment 22:
right click on /src/main (where you have /java and /res folders),
select New > Folder > Java Resources Folder,
click Finish (do not change Folder Location),
right click on new /resources folder,
select New > Directory
enter "META-INF" (without quotes),
right click on /resources/META-INF folder,
select New > Directory
enter "services" (without quotes)
copy any file you need into /resources/META-INF/services
For you, in step 10 above you'd need to copy this file into /resources/META-INF/services. In case the file link is broken in the future, the name of the file is javax.xml.stream.XMLInputFactory and it consists of a single line:
com.fasterxml.aalto.stax.InputFactoryImpl
EDIT
If you get a "Error:duplicate files during packaging of APK... Path in archive: META-INF/services/javax.xml.stream.XMLInputFactory", you can try telling Gradle to keep the first occurrence with:
android {
packagingOptions {
pickFirst 'META-INF/services/javax.xml.stream.XMLInputFactory'
}
}
EDIT 2
This bug may be affecting "pickFirst". Please make sure you're running the latest version of Android Studio, and update your local tools and Android Gradle plugin to make sure you're running the most recent version of the tools. This may be fixed in Android Studio 1.3 RC1.
I have attempted to add XmlPull support to jackson xml. Find the forked project here:
https://github.com/finvu/jackson-dataformat-xml
Currently, only supported for version 2.9.6. (clone the branch jackson-dataformat-xml-2.9.6-XmlPull)
Sorry, I am not able to provide detailed documentation due to time constraints. If you have knowledge of git and maven to pull a specific branch and build the jar, then it should be relatively easy.
To those who will be in need of this in the future:
first integrate Jitpack in Your Android app, following their instructions:
https://jitpack.io/
Then paste teh GitHub url of jackson-dataformat-xml on Jitpack sites' corresponding text box. GitHub url is:
https://github.com/FasterXML/jackson-dataformat-xml.
That's it! Enjoy the result. :)

How to override a java library in plugin development environment

I develop an application in a "special" plugin-development environment.
This environment needs to include some java libraries by default so that the created plugin-application can be exported and used successfully.
The problem is now that the plugin-environment comes with an old "javax.mail" library. It is not supported to override this library in the environment.
Of course it is possible to include the newer javax.mail library into my plugin-application but the library is not recognized and the old library is used.
Question:
Is it possible to force a Java Application to use a special included library which is using the same package and class names like a "native" library from a "plugin-environment"?
What I have tried:
I tried to rename the package files within the custom library "javax.mail" to "javax_external.mail" and to use something like this in my application:
javax_external.mail.Session session = javax_external.mail.Session.getDefaultInstance(props);
But I get the error: Type mismatch: cannot convert from javax.mail.Session to javax.mail.Session

Categories

Resources