How to load a resource from disk in OSGI environment - resources

Part 1: I've been trying to load a (XML) file as a resource from disk using bundle class loader. I can't package the file in a bundle beforehand as it'll be generated at runtime. I tried searching too, and almost always, people talk about loading resources from within a bundle (either same or different). So is it even possible to load a resource from disk in an OSGi environment using bundle classloader? If yes, how can it be done?
Part 2: Now I need to add a constraint to the above. In my complete scenario, while I'd be generating the file, it would be loaded by a third-party bundle. In this case, what could be done (generate in a certain location, any changes to classpath etc.) so that the third-party bundle's class loader could find the generated file?
Using: apache karaf 3.0.2, ubuntu 12.

Part 1:
So is it even possible to load a resource from disk in an OSGi environment using bundle classloader?
Resources (read-only files on the classpath) can be loaded with classloaders, not ordinary files from any folder of the disk. When you want to process the content of files from the ClassPath, you should use the classloader.
You want to generate a temporary file (generated and processed at runtime) so you should use the standard Java API for that:
File myTmpFile = File.createTempFile(...);
For more info, see the javadoc of this function: https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String)
Part 2:
The third bundle should have an API that either accepts a File, URL, Path or other type instance that can point to a file in the file system.

Related

WS02 ESB - How to get Custom java class property file on the classpath

I have loaded a custom jar file into WSO2 by placing it into the /repository/components/lib directory, performing a restart. I then call that class from a script mediator using inline groovy. The groovy script recognizes the class, however the custom class is attempting to load a properties file that must be on the classpath. I have put that property file nearly everywhere but I keep getting an error that it cannot find the file on the classpath.
I am running the standalone WSO2 ESB 4.7.0. I have put the file as part of the jar, I have also attempted to place it in several directories within the WSO2 file structure as well. All to to avail.
you could try to register a resource in the carbon registry and add a Property to this Resource. Basically there are two ways (in java...):
Here is an example how to connect to the registry via a service with the PropertiesAdminServiceStub: http://www.massapi.com/class/org/wso2/carbon/registry/properties/stub/PropertiesAdminServiceStub.java.html
The most important here is that you authenticated your user, the result is a cookie which yoou have to add to the stub.
The other would be something like this (probably a duplicate of your question)
I am unable to get the list of services with in the applicaton i.e.; wso2 governance registry? I am working with binary code
The last one asumes that the carbon-context is available, means you are running the search inside the wso2 like a feature for example.
Unfortunately there is no place to put that properties file. Luckily this jar file, is an in house entity. It was written to search the classpath for the properties file and upon not finding one on the classpath to throw an exception. We ended up rewriting the code that loads the properties file to upon not finding the file on the classpath to search in a directory which we specified as a system environment variable in the wso2server.sh file. Not very elegant, but it is working perfectly.

Remove configurations from unrelated environments when building a Grails WAR

When building an environment-specific Grails WAR file configurations from other environments are included in the WAR file as well. For example, all the database connections properties from the production environment are also included in a WAR file built for test. Even though the configuration is compiled to class files it's quite simple to extract sensitive data from there.
In order to improve security, I want to exclude unrelated environment configurations from a WAR file. Is there a way to strip this configuration automatically during the WAR build or do I have to externalize these configurations and deploy them separately?
I suppose if you could somehow analyse the bytecode and work out precisely which Config$_closure3$_closure12 corresponds to the bit you don't need then you might be able to replace it in the war with an empty closure, but it's probably more hassle than it's worth. There's certainly no easy way I'm aware of.
I would put the config for each env in a separate file. If you put the prod config in web-app/WEB-INF/classes/myapp-prod.groovy (still in an environments block) and the dev config in a file in the top directory, and say
grails.config.locations = ["classpath:myapp-prod.groovy", "file:myapp-dev.groovy"]
then only the prod configuration will end up in the war. Though it would be completely human readable, so it may be more secure to simply leave the prod config directly in Config.groovy (so it gets compiled) and just use the external to override for dev mode.

How to generate a javadoc in XPages

When I try to generate a javadoc, using the menu command Project\Generate Javadoc, the following warnings and error are produced for my custom classes in XPages:
javadoc: warning - No source files for package net.focul.utilties
javadoc: warning - No source files for package net.focul.workflow
javadoc: error - No public or protected classes found to document.
The packages are in the WebContent/WEB-INF/src folder which is configured in the build path and are selectable in the Generate Javadoc wizard. The classes are public with public methods.
Javadocs are generated for all of the Xpage and Custom Control classes if I select these.
You're experiencing this behavior because javadoc doesn't understand the Designer VFS (Virtual File System). It assumes that your project consists of a bunch of separate files in some folder structure on your local hard drive, not self-contained inside a single NSF. On the whole, the Designer VFS successfully tricks Eclipse into believing it's interacting with local files by intercepting read/write requests for project resources and importing/exporting DXL or CD records, etc. But apparently they haven't applied this sleight of hand to javadoc as well.
The Java source files corresponding to each XPage and Custom Control are processed successfully because, ironically, they are never stored in the NSF. During every project build, Designer discards any of these it has already generated and re-creates them based on the current contents of the various .xsp files. It then compiles those Java files into .class files, which are stored as design notes inside the NSF. At runtime, it's these files that are extracted from the VFS and executed... the source code no longer matters at this point, so there's no reason to ever bother including the .java files in the NSF, so they're just kept on the hard drive. One indication of this behavior is that the folder is named "Local" when viewed in Package Explorer / Navigator.
If you're using the built in (as of 8.5.3) version control integration (see this article for a great explanation of how to use this feature), you can tweak the Build Path to include the copy of the src folder stored in the on-disk project as a "linked source folder". This causes javadoc to consider the duplicate copies valid source files, and therefore includes them in the generated documentation. On the downside, it also causes Designer to consider them valid source files, which causes compilation errors due to the duplication. So this approach is only viable if you only need to generate the documentation on an infrequent basis, and can therefore break the Build Path temporarily just to run javadoc, then revert to the usual settings.
An alternative is to actually maintain your custom Java code this way on an ongoing basis: instead of creating the folder in WEB-INF inside the NSF, just create a folder on your hard drive that stores the source, then include that location as a linked source folder indefinitely. That way Designer can still find the source, but so can javadoc. NOTE: if you go this route, then you definitely need to use SCM. Because your source code no longer lives inside the NSF, providing the convenient container we're used to for getting the source code to other developers and ensuring inclusion in whatever backup schedule you use, the only place your source code now lives is on your local hard drive. So make sure you're regularly committing those files to Git / Subversion / Mercurial, etc., or, at the very least, storing them on some file server that is backed up regularly and, if applicable, accessible to all other members of the project team.
When you expand the net.focul.utilties in Designer, you will see all the methods and properties. But when you click on on of the methods, you will see neo source code.
So this is where javadoc fails to generate the documentation. I guess that the author of the application has not provided you with the source code. If you have the source somewhere, you can attach this code and then javadoc will be able to generate the documentation.
I run into the same situation and I have found the most straightforward method is to export the source to an external folder and then use regular Eclipse to generate the JavaDoc. Not sure my process is any less of a hassle than Tim's suggestions but for me it just feels less risky than trying to deal with the VFS vagaries.

Standard location for external web (Grails) application config files on linux

Is there a standard location on Linux (Ubuntu) to place external config files that a web application (Grails) uses?
UPDATE: Apparently, there is some confusion to my question. The way Grails handles config files is fine. I just want to know if there is a standard location on linux to place configuration files. Similar to how there is a standard for log files (/var/log). If it matters, I'm talking about a production system.
Linux configuration files typically reside in /etc. For example, apache configuration files live in /etc/httpd. Configuration file not associated with standard system packages often live in /usr/local/etc.
So I'd suggest /usr/local/etc/my-grails-app-name/. Beware that this means you can't run two different configurations of the same app on the same server.
I don't believe there is a standard location. You usually define the location for your external config files via the grails.config.locations property in config.groovy.
EDIT
After reading your comment, I suppose the standard locations would be:
Somewhere on the classpath
OR
In the .grails folder in your home directory.
As these are the defaults in config.groovy file.
grails.config.locations = [ "classpath:${appName}-config.properties",
"classpath:${appName}-config.groovy",
"file:${userHome}/.grails/${appName}-config.properties",
"file:${userHome}/.grails/${appName}-config.groovy"]
There's a plugin Standardized external configuration for your app which you might find useful if the grails.config.locations parameter is insufficient.

About Maven resources

From the stand point of a Maven project, should files stored there be accessed in any special way or be treated as any other file where "resources" is just another directory?
What makes this directory special? Is it fair to say that "resource" is anything that is not a source file and that is used by a program?
I am a bit confused here. Please clarity
All files in the resources directory get added to your jar (or war) without being compiled. Generally things like config files or other non-source resources are put in this directory, although as long as your files don't end in ".java" they could live in the sources directory and the resulting artifact would be the same.
To access a file in the resources directory you would use the ClassLoader.getResource or getResourceAsStream methods.
The other feature of resources when using Maven is that you can include property tokens that will be replaced by Maven as part of building your project. For instance:
This line in a resource file
artifactName=${project.build.finalName}
Would be replaced with something like:
artifactName=my-project-1.0.0
Any of the properties available within Maven can be replaced in your resources.
It's just a standard. By default, the contents of the resources directory are copied to the same target directory as the .class files and, if packaged as a jar, in the root of the jar.
You can also specify how resources are encoded. If you don't, you effectively preserve the encoding of the system on which you built, which is non-portable and is something Maven will warn you about.

Resources