I'm developing a main application whose features can be extended via jar files that contain plugins. When my application runs, it simply checks the folder for the plugins, and loads up the classes that it finds there and registers them with my application.
I'd like to develop a help / messages sub-system to my application that uses external resource files (HTML files if possible) to get the help content associated with various parts of the application and to get detailed info/warning/error messages to display to the user.
For all things that pertain to the main application, I can easily determine the relative path to the resource file since I'm keeping those resource files in the same jar as my application class files.
For external plugins, ideally the resource files pertaining to that plugin should live within the jar for that plugin. However, I'm not finding a consistent way to determine the path to those files in the dynamically loaded jars.
Would appreciate any insight into how I could consistently do that for both internal resources and externally provided resources to use the same help / messaging framework provided by the main application.
If you are trying to load the file from a different plugin, or from the main application code, you'll need an instance of the pluginManager from Spring:
InputStream in = pluginManager.getDynamicResourceAsStream(filename)
Ref: https://developer.atlassian.com/confdev/development-resources/confluence-developer-faq/what-is-the-best-way-to-load-a-class-or-resource-from-a-plugin
Related
We are using Websphere 9 application server. We want some of the configuration files such as xml and properties files in a separate directory of Websphere server and want them too see accessible by ear/war file during the run time. I heard about shared libraries approach, but it apppears that only class and jar files can be used as shared libraries, but not xml and other files. Can anyone tell me an alternative solution where the external xml configuration files be made available for war/ear file during run time or in class path?
If you add a directory as a shared library path, the directory itself will be added as a class path entry to any class loader referencing the shared library (along with any jar/zip files within it), so you'll have access to loose files such as XML files through the getResource() API.
Note that the argument to getResource() needs to be relative to the location within the directory. For example, if you have the file test.xml, you could add it to the directory /sharedlib, created a shared library named "library1", and associate it with your EAR or WAR, and then your application could use use this to get at the file:
this.class.getResource("test.xml");
That would return you a URL pointing at /sharedlib/test.xml.
I am writing a Quarkus application which reads data over http. In my application.properties file, I have this line:
my.resource=http://path/to/file
Every time I run the app, it has to download the file so I created a smaller version of the file locally for developing purpose. The problem is that I don't know how to put it in the properties file.
Ideally, I want something like this:
my.resource=http://path/to/file
%dev.my.resource=file://${project-dir}/sample_data/file
And I have to use the absolute path because I used new URI(resource).toURL() method which requires an absolute URI.
Thanks in advance.
Application properties is something that is used when your application is deployed to adopt your application to the target environment, does the user of the deployed application know anything about project directory? Project directory is something that makes sense when you are developing your application. having said that using project directory in that file does not make sense at all.
I am facing a little strange issue while deploying web service to WAR file.
If I deploy the application via Netbeans IDE it is going under \standalone\deployments directory.
However, if I deploy the war file from Admin Console it is always getting deployed at \standalone\tmp directory.
Please guide on this issue. The deployment should go under \standalone\deployments directory only.
The deployment should go under \standalone\deployments directory only
You are quite not right.
It is not an issue. It is what it is.
standalone/deployment folder stand there only for "hot-deployment" functionality available only with standalone mode.
So, Netbeans uses it. You can do the same just by saving EAR or WAR into standalone/deployment and server will pick it. (default scan interval is 5 sec.)
but Admin console or CLI is only (and standard) way to deploy application on domain. In domain mode deployment folder is not in use and there is no deployment scanner.
Then when you use console it goes common way - deploys as on domain regardless is it domain or standalone server.
Updated / follow-up:
In general it is better to keep .properties file(s) out of deployment, in separate location. It is main idea behind them - to be able to change properties without application rebuilding and redeploying. Usually properties are different in different environments (DEV/UAT/PROD)
So there are 2 most popular solutions:
store properties in different location add that location to class path and access them through ClassLoader.getResourceAsStream() mechanism
store properties in different location, pass that location through system (or -D) variable and access them as file. for JBoss you can place your .properties under configuration directory. there is already JBoss variable. Kind of jboss.config.dir (or such, you can find it in Admin console, I do not have JBoss right now).
But of course sometime it still needed to access resources inside WAR/EAR - in that situation it is pretty much the same as first solution above.
Just be sure your .properties file(s) are accessible through to ClassLoader (in class path) and use them from ClassLoader.getResourceAsStream (or if you use Spring point it as "classpath:" not as "file:".
I have two modules that will use ESAPI with the same properties files (ESAPI and validation.properties).
These modules output to wars that are contained in an ear.
I have the properties files inside one of the war files, where they are found at server start. The other war file seems to work fine and does not complain that it can't find the properties files in the log.
I am using ESAPI to sanitize html and url parameters - I wonder if I even need these property files to be accessible to the second module, or either one since there is no configuration and everything is being done with defaults.
First, let me describe how ESAPI 2.x goes about finding its ESAPI.properties file.
The reference implementation class for ESAPI's SecurityConfiguration interface is
org.owasp.esapi.reference.DefaultSecurityConfiguration
With this default implementation, resources like ESAPI.properties and
Validation.properties can be put in several locations, which are searched in the following order:
1) Inside a directory set with a call to SecurityConfiguration.setResourceDirectory(). E.g.,
ESAPI.securityConfiguration().setResourceDirectory("C:\myApp\resources");
Of course, if you use this technique, it must be done before any other ESAPI calls are made that use ESAPI.properties (which are most of them).
2) Inside the directory defined by the System property "org.owasp.esapi.resources". You can set this on the java command line as follows (for example):
java -Dorg.owasp.esapi.resources="C:\temp\resources" ...
You may have to add this to the start-up script that starts your web server. For example, for Tomcat, in the "catalina" script that starts Tomcat, you can set the JAVA_OPTS variable to the '-D' string above.
3) Inside the
System.getProperty( "user.home" ) + "/.esapi"
directory (supported for backward compatibility) or inside the
System.getProperty( "user.home" ) + "/esapi"
4) The first ".esapi" or "esapi" directory encountered on the classpath. Note this may be complicated by the fact that Java uses multiple class loaders and if you are have multiple applications in a given application server, they may be using different classpaths. For this reason, this option is not generally recommended, but is offered for reasons of backward compatibility with earlier ESAPI 1.4.x versions.
Once ESAPI finds a valid property file (e.g., ESAPI.properties) that it can read, it stops searching for others.
Now, that said, if you want to share a single ESAPI.properties file across all of your .war files, I would recommend going with option #2 and set the System property "org.owasp.esapi.resources" to some common secured directory that both of them can access. Also, you should use a full path name.
The answer was to place the esapi directory containing the properties files in
src/main/application
in one of the modules. This path puts it's contents at the root of the ear.
I'm running ESAPI on a maven project with java 1.8.0_71. I've put ESAPI.properties and validation.properties in
src/main/resources
This worked for me:
Attempting to load ESAPI.properties via the classpath.
SUCCESSFULLY LOADED ESAPI.properties via the CLASSPATH from '/ (root)' using current thread context class loader!
Attempting to load validation.properties via the classpath.
SUCCESSFULLY LOADED validation.properties via the CLASSPATH from '/ (root)' using current thread context class loader!
I have a client/server system that is passing messages using MIME format. I have created some custom mimetypes using the JavaBeans activation framework.
I have created a simple java project with the following:
my-mime
+- src/com/foo/FooContentHandler
+- META-INF/mailcap
+- META-INF/mime.types
mailcap:
application/x-foo; ; x-java-content-handler=com.foo.FooContentHandler
mime.types:
type=application/x-foo desc="foo" exts="foo"
I have demonstrated this working in a standalone testcase. However, when I add it as a plugin the MIME type doesn't get picked up. I presume that this is down to the fact that the Java Activation classes can't see my custom mime type definitions.
How can I add them to my bundle so that they are picked up?
Make sure your project is a Plugin Project, and make sure the build.properties has your mailcap and mime.types checked as exported (open the manifest and use the Build tab).
I realize it's been a while since you asked this question, but anyway...
Looks like your RCP application cannot read the file.
First, make sure the mailcap and mime.types resources are owned by the same plug-in that tries to access them.
Secondly, try to construct MimetypesFileTypeMap with explicit mime-type file specification.
Start with static file and absolute file path e.g. /tmp/mime.types and if that works then your problem is resource loading indeed. In that case, get stream from plugin and construct your MimetypesFileTypeMap with that stream.
In my project I had two RCP plugins. One contained Java Mail jar and all its dependencies, including activation.jar. Another contained custom code for composing and sending mails.
Initially, I tried to use MimetypesFileTypeMap in the second plugin and identify MIME type using class method getContentType(String filename). mime.types file was placed in plugin`s META-INF folder. The problem was almost the same. MIME types identification worked perfectly when RCP app was launched from IDE, but failed when it was launched as export RCP app.
But then I find out that Java Mail tries to identify MIME types but itself while, for example, attaching files to an email. And it uses its dependency activation.jar. After that I needed to solve the problem about how to force activation.jar to find correct mime.types in the scope of the first plugin.
But the only way I found was repackaging activation.jar and adding correct mime.types in jar`s META-INF folder. Unfortunately, this solution is not perfect as it "hacks" third-party library .
From https://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/javabeans/glasgow/javadocs/javax/activation/MailcapCommandMap.html
Mailcap file search order:
The MailcapCommandMap looks in various places in the user's system for mailcap file entries. When requests are made to search for commands in the MailcapCommandMap, it searches mailcap files in the following order:
Programatically added entries to the MailcapCommandMap instance.
The file .mailcap in the user's home directory.
The file /lib/mailcap.
The file or resources named META-INF/mailcap.
The file or resource named META-INF/mailcap.default (usually found > only in the activation.jar file).
From a now-dead link:
JAF uses the context class loader to load classes. If that fails,
it uses the class loader that loaded the JAF classes.
When JAF is packaged with the application, the JAF classes are
loaded by the same class loader as the other application classes,
so even if the context class loader isn't set JAF can find the
other application classes.
When JAF is part of the JDK, the JAF classes are loaded by the
system class loader. Without the context class loader being set,
JAF has no way to find the appropriate class loader to load
application classes.
An example of programatically setting the MailcapCommandMap is:
static { // add handlers for main MIME types
MailcapCommandMap mcap = new MailcapCommandMap();
mcap.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mcap.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mcap.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mcap.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed; x-java-fallback-entry=true");
mcap.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
CommandMap.setDefaultCommandMap(mcap);
}