Don't load/scan class files from a specific jar - apache-felix

I'd like to know how to configure the maven-bundle-plugin (backed by bnd) to completely ignore the classes contained within an embedded jar.
Background
I'm working in a controlled environment where the environment my code is running on is defined by a single company (including all the tools). The code is java and uses OSGi to define module dependencies.
Some of the provided modules contain what look like invalid class files, I can only assume that the system will 'correct' these class files before it tries to load them into any type of JVM. In any case these class files work when deployed onto the target system.
I'm trying to create a build system based on Maven that can produce packages the system understands and have hit a problem where these invalid class files are being read by BND (via apache-felix) which causes errors.
I'd like a way to have the jars that contain these class files on the class path of the bundle but where the contained .class files aren't read/processed by bnd. I could settle for simply ignoring the errors and continuing but can't find a way to do that either without felix aborting the entire build phase.

I just found the -failok directive, don't know why I didn't find it before. Adding <_failok>true</_failok> to the instructions allows me to continue working.
See instructions-ref

Related

Generating XML Resources into Classpath using Annotation Processors

I am currently working on a Gradle 3.3 project in Intellij 15.0.6.
I am using the Gradle APT plugin to add annotation processors to my classpath.
It works fine when generating Java class files, however I need to be able to generate XML sources within the resources directory equivalent in the build directory's generated directory.
Here is my build directory structure currently:
Project Build Directory Image
As you can see, it does not include a resources directory, which I suspect is what may be causing this problem.
The current exception I receive from running my annotation processor via ./gradlew assemble is: java.lang.IllegalArgumentException: Resource creation not supported in location CLASS_PATH
The code I am using within my annotation processor to generate the xml file:
FileObject source = processingEnv.getFiler()
.createResource(StandardLocation.CLASS_PATH, "", "ap-test-2.html");
Note: I used an HTML extension just as a test, XML should produce the same results.
javax.tools.StandardLocation has other output locations as well:
The SOURCE_OUTPUT location worked to place the XML within the same package as the generated Java classes, within src/apt/main. This is not my desired behaviour however. I need them to reside within the classpath.
I have not found this exception discussed anywhere else after extensive research.
Any help is appreciated. Thank you for reading this question.
StandardLocation.CLASS_PATH is only for input, not output. The only output locations are SOURCE_OUPUT (the build/generated/source/apt/… folder), CLASS_OUTPUT (the standard Gradle build/classes/…), and NATIVE_HEADER_OUPUT. See https://docs.oracle.com/javase/8/docs/api/javax/tools/StandardLocation.html
JavaC has no notion of classes vs. resources outputs, but if you run your annotation processor during your compilation then CLASS_OUTPUT should work (Gradle should then copy everything into the final directory/JAR). See https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html

Manifest.MF vs libraries.xml vs deployment.xml

So I am having issues deploying code to my local websphere server (imagine the dred I have for installing it to my test server).
I get a java.lang.ClassNotFoundException when I attempt to run the application.
So after googling around it seems as though I need to add entries into one of the above files. Problem is, there doesn't seem to be good examples of how to do that.
In the Manifest.mf file, do I need to add the fullpath to where I expect the jar to be? Does anybody have a good example of a deployment.xml/libraries.xml? How do I translate what is in my project classpath to entries into those various files?
Start with 'Websphere Class Loaders'.
Usually the order to load/find a class/resource is :
Current Module(war/jar/sar) --> (if not found then look inside) -->
Another Module in EAR (via manifest.mf) --> (if not found then try to load it from) -->
Common shared library (libraries.xml) (or) Extensions library -->
(if not found, then throw the error Class not found/No class Def found error).
Manifest.mf
Using this file you could point to the module/location directly to load the required classes/resources.
libraries.xml
Here you can define and maintain the shared libraries which can be used across many JVM's (like single jar file can be referenced from multiple jvm instances). Refer this for more information.
In my experience, I try to avoid using manifest.mf files, and refer the library jar files from shared library 'libraries.xml' file. (or) if you are trying to learn the Web sphare, then just include the jar files in lib/ folder of your package.

Using JavaCompiler with Classpath referencing jars within ear

I am working on a project in which an enterprise archive (ear) deployed on a JBoss server needs to compile (and run) a class dynamically. I am using the JavaCompiler class to do this - the complication comes from the fact that the class being compiled has references to some of the classes contained within the ejb jar within the ear.
This is not a problem when the deployed ear is 'exploded' on deployment, so it is just a directory rather than an archive - in this case I am able to specify the required jar in the -classpath option of the compiler, and compilation works fine. Unfortunately due to constraints of the systems I am working with, it is not an acceptable solution to deploy these ears 'exploded', and the compiler seems not to be able to 'see' the required jar when it's wrapped up in an archive.
Given that the dynamic compilation is taking place from the ear in question, and therefore the system's class loader has access to the contents of the required jar, is there any way I can tell the compiler to just use the classes as loaded by the system class loader?
I appreciate this is something of a wordy question, but any help would be appreciated.
Thanks
It seems that there is no simple way to have the JavaCompiler load dependencies of compiled code from a ClassLoader. However, one could implement JavaFileManager directly and redirect the operations for the StandardLocation.CLASS_PATH using resource lookups on the context ClassLoader (getResource(<class/resource name>)). This would withdraw the limitation of StandardJavaFileManager directly operating on Files.
Someone already seems to have prototypically implemented that approach:
http://atamur.blogspot.de/2009/10/using-built-in-javacompiler-with-custom.html

Class loading when extending an Eclipse plugin with a fragment project does not work

I am trying to extend a third-party Eclipse plug-in by using a fragment project. The major reason is that the third party plug-in contains classes having the default (package) modifier and I need to extend them.
Thus, my extensions class must be located in exactly the same package. I create a fragment project containing the same package and put my class into it. Everything works fine when I am using a runtime workspace.
However, if I try to deploy my fragment (e.g., deploying it into the dropins folder of my Eclipse distribution), I am not able to execute the code. Extensions and stuff like that work fine (e.g., I use extensions for a new Run Configuration. However, if I try to instantiate this run configuration I get an error message that the third-party root plug-in was unable to load the class to display my configuration tab group.
Any experience with this kind of problems?
Sorry, but that does not work. Unless the host bundle has been crafted specially for it, you cannot override a class in the host from a fragment. The reason is that resources - including classes - are retrieved from the host before any fragment.
See org.eclipse.osgi.baseadaptor.loader.ClasspathManager for the implementation..
Actually, this is the extension code I am using:
<extension point="org.eclipse.debug.ui.launchConfigurationTabGroups">
<launchConfigurationTabGroup
class="com.android.ide.eclipse.adt.internal.launch.jouleunit.AndroidJouleUnitTabGroup"
id="com.android.ide.eclipse.adt.jouleunit.AndroidJouleUnitLaunchConfigTabGroup"
type="com.android.ide.eclipse.adt.jouleunit.launchConfigurationType">
</launchConfigurationTabGroup>
Of course, there are further extensions definig the launch configuration type etc. but this is the one leading to the class which Eclipse can not find.
Actually I found the problem now for myself. The problem was a wrong configured build properties file which excluded the Java byte code from my fragment JAR. Very itchy, as the classes were in the JAR but in a wrong subdirectory.

Elicpse CDT thinks it's broken

I'm using Eclipse for some embedded development and recently is started to give me these errors every time I save a file or do a build. It's annoying but for the most part it doesn't seem to be causing any problems (It even still highlights warnings/errors int the source. What's going on here?
Plug-in org.eclipse.cdt.cross.arm.gnu was unable to load class
org.eclipse.cdt.managedbuilder.internal.scannerconfig.DefaultGnuWinScannerInfoCollector.
Plug-in org.eclipse.cdt.cross.arm.gnu was unable to load class
org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedGCCScannerInfoConsoleParser
It looks like the eclipse wiki FAQ says
The most likely reason is that an exception was thrown in the static initializer for a class declared by the offending plug-in. Check the .log file to see whether that indeed happened.
The Eclipse Platform loader will not load a plug-in when exceptions are thrown during the initialization of the Java classes that make up the plug-in.
Another common reason for this error is the lack of an appropriate constructor for the class being loaded. Most classes declared in extension points must have a public zero-argument constructor. Check the extension point documentation to see what constructor is required for the classes that you declare in an extension.
If the problem only occurs when deploying a packaged plug-in (i.e., when it is not started in a runtime workbench via PDE) it is usually a good idea to check the Bundle-ClassPath attribute in the MANIFEST.MF file.
The JAR file that contains the plug-in classes must be listed in the Bundle-ClassPath. Even if the plug-in's proper classes are all listed, class loading may still fail because a .class file may contain references to other classes that cannot be resolved at runtime. In this case, the missing classes need to be identified (usually by looking at the import statements of the problematic class) and the necessary entries need to be added to the Bundle-ClassPath. If additional JAR files are required, those JARs also need to be listed in the build.properties file so that they are included when the plug-in is packaged.
(See this thread as an illustration of that last point)
So, for instance, in this thread, for another issue back in eclipse3.0 time:
The plugin.xml file specifies "org.eclipse.core.runtime.compatablity" as a required plugin. However, I am using Eclipse Version 3.0.1 and should be using "org.eclipse.core.runtime_3.0.1".
Solution:
Replace the line in the Plugin.xml
<import plugin="org.eclipse.core.runtime.compatability"/>
with
<import plugin="org.eclipse.core.runtime"/>
VonC is right -- with a fair bit of detail on what might go wrong with class loading...
In this case, your arm.cross toolchain is referencing internal classes in CDT's managedbuild which aren't accessible. This is an incompatibility between your arm toolchain and CDT. You should file a bug with them on this error, first trying a newer version.