How to override shared resources including in dependency JAR - java

I've got a few web projects that rely, all of them, in a common library. This library includes a few JSP files that are used to display errors (using the web.xml error-page feature). These JSP files are included in the library shared-resources, so they are merged with the files from the application.
What I'd like would be for a way to override thoses files with ones specific to the application if I want. If I include files with the same name in the same location in the application, they are overwritten by those in the library. Is there a way, maybe using maven plugins, so I can copy files from the application AFTER the ones from the library have been copied to the target directory? This way, if the application includes its own files, they are used. If it doesn't, then those in the library are used instead.
I've tried adding a new execution of the maven-resources-plugin, using the goal copy-resources, but they still get overwritten by the ones in the library.
Thanks for the help in advance.

Related

How to add external third party jar in Notes Xpages application?

I am Java developer, recently working on Xpages project. we are using Notes 9.0.1. I created Java agent to send email and I want to use some third party jar, something like org.apache.commons.lang3 , end up this issue. how to add third party jar, like commons-lang3-3.4.jar, in my Xpages project?
I tried different ways
add jar under /jvm/lib/ext folder, restart DDE.the I can see it in
my project JRE system libray, but could not import in my Java code.
Maybe this is the way for server deployment.
add jar under /Code/Jars and then DDE generated with new name added in /Webcontent/WEB-INF/lib, but...
Add jar directly under /Webcontent/WEB-INF/lib, but not appeared /Code/Jars in Application view
add jar under the Java agent Archive folder, but...
None of them allows me import the package in my Java code.
Anything I did wrong, or is there any good way to add third party jar in XPages project.
Thanks
If you add a JAR to your project by importing it into /Code/JARs, it should be added so as to be accessible by your build path(2,3). The same is true of your /WebContent/WEB-INF/lib, but that may not be automatically defined in your version of DDE; for example, Domino Designer 9 has the design elements of /Code/Java and /Code/JARs, which didn't previously exist (these are separate folders/paths from /WebContent/WEB-INF/src or /WebContent/WEB-INF/lib, either can be in the build path). In either case, if your approach is to have the JAR in your NSF, make sure your build path has the path with your JARs. Separately you could add each JAR individually.
You can get to the Build Path via Project > Properties, then for the part of your build path concerning JARs, go to "libraries":
individual JARs in Project Build Path
JAR class path in Build Path (ex- /WebContent/WEB-INF/lib)
As for the path of using the /jvm/lib/ext folder approach, I've covered that in a blog post and it's important to remember to have the JARs in the appropriate relative path both on the server and in your Designer/local path (otherwise your local, DDE, may not pick up the change).(1)
For both, if you keep build automatically turned off, you'll want to make sure you perform another build to see the changes.
As for a Java Agent archive, this should just work and again I'm wondering whether your build automatically setting is enabled/disabled. The /jvm/ext/lib path ought to work for this as well (shown in my linked blog post).(4) *Note: as Paul Withers points out in the comments, importing a JAR to a Java Agent can introduce memory leak issues, making the /jvm/ext/lib/ path preferable.

Missing jar file error

I am developing an application with many functionality, where one functionality requires a jar file which is only commercially available. When I release it for public use for free, I have to remove this jar file from my source. When I run this application in Eclipse IDE with the jar file removed, it gives me "Errors exist in required Project". I would like to avoid this warning.
Only the users using the library should be able to access its corresponding functionality (The application has many functionality.)
Users who don't include this jar file should be able to access other functionality without any error/warning.
Requirement:
Gray out the functionality based on the absence of the jar file.
Avoid the warning message when I run the Main.java
Any help appreciated. Thanks!
What you need indeed is dynamic class loading, isn't it?
To enable this feature, you have some options:
Implement your own classloader.
Use OSGI.
Additional to yanana's solution, you can simply leave the commercial JAR file in your Eclipse project. When creating your setup you can create one setup for commercial use (including the JAR) and one for the open source version (without the JAR).
But you should be carefully separate the usage of the commercial classes into one or more package/module. At runtime you can check the presence of one class which is part of the commerical JAR file via reflection before accessing code dependent on the commercial JAR.
Your integration tests should contain some corresponding test cases with and without the commercial JAR in classpath.

Including property files in a complex project

I have two eclipse projects.
One of them is a library that contains property files.
Second one is a Dynamic Web Project.
In my library there are few configurable classes, that load their configuration parameters from property files.
String path = "Resources/Properties/Main.properties";
InputStream stream = getClass().getClassLoader().getResourceAsStream(path);
Properties properties = new Properties();
properties.load(stream);
My dilemma is that when I export my Web project into WAR, dependent library project gets packed into a jar and placed inside my WAR into "WEB-INF/lib" directory, which means that I can't load them as I would usually do.
My ideas are:
Copy those property files into my Web Projects, which is very
painful, because this library is meant to be used in many projects,
I do not want to have multiple instances of property files scattered
around projects.
Place property files into some system fixed path on the server, still is a bad desigion, makes it harder to deploy this application.
Is there a way to load property files from JAR files, or maybe a way to tell eclipse project to export property files from my library into my Web Project explicitly?
I would appreciate your help and ideas on this matter.
It works just fine if you load the resource file from classpath.
It goes trough classpath and searches for matching resource.
My problem was classpath resource collision, I had classes with similar package.classname and resources with similar path and filename.
When loading these resources, JVM silently ignores duplicated entities from .jar libraries.
So stay sharp and beware of non-unique entities when composing a complex library structure.

Why some resource files are put under META-INF directory

I am wondering why some resources files are put under the META-INF directory in the JAR? I am always put the resources like test.properties under the root diretcory. Any advantage to put them in the META-INF?
Lot of Java (EE) APIs have a contract that when you put a specific configuration/metadata file in the META-INF folder of your (or a 3rd party) JAR, then the API will automatically do the API-specific job, such as scanning classes, preloading specific classes and/or executing specific code based on the meta information.
An example provided by the standard Java SE API is the ServiceLoader. Among others, the JDBC 4.0 compatible drivers implement this. This way just dropping the JDBC driver JAR file folder will automatically load the driver class during Java application's startup/initialization without the need for any manual Class.forName("com.example.Driver") line in your code.
Further there is also the Java EE 6 provided JSF 2.0 API which scans during application's startup all JAR files for a faces-config.xml file in the META-INF folder. If present, it then will then take it as a hint to scan the entire JAR file for classes implementing the JSF specific annotations like #ManagedBean so that they get auto-instantiated and auto-configured. This saves time in potentially expensive job of scanning thousands of classes in all JARs in the entire classpath. In older versions of those API's the configuration was usually done by (verbose) XML files.
All with all, the major goal is to save the developer from code and/or configuration boilerplate. The JAR's META-INF folder is used for configuration files/hints. Some API's indeed also put static files/resources in there for own use. The META-INF folder is also part of the classpath, so the loading of those files by the classloader is easy done.
In servlet 3.0, certain static resources are available through the web context, such as .css, java script, and .png files, so you no longer need to use ServletContext getResource() and getResourceAsStream(). For more information, check out web-fragment.xml (https://blogs.oracle.com/swchan/entry/servlet_3_0_web_fragment) which is one resource that covers this subject.
Personally, I prefer to structure my projects the way Maven likes them, with a src/main/resources directory which is part of the application's classpath.
It's just a convention that some (most?) third party jars use to look for files that you provide. For your own classes and files, you can choose to put them where you like.

How should I structure my project to share classes between an Android client application and a JSP server application?

I'm building an Android application (as an Eclipse project) that needs to access a web service. We will be sending the data from the service as JSON serialized classes, so we want to share some of the classes between the Android application and the server application. We are currently thinking that the way we need to do this is to structure our Git repository with 3 folders. One for the client, one for the server, and one for the shared library.
But at that point we couldn't figure out how to create the shared code. It looks like we can put all the .java files into a folder and then create a relative link to that folder from the other projects, but is that a good way to go about this?
The other possibility we found was to create another project in Eclipse and then include the library project in the client project. However we ran into a problem here. How can we make the library usable by both the server and Android? If I create a new Java project in Eclipse, I must select a JRE to build for, but Dalvik isn't an option, and even if it was how could I use the library with a desktop VM if the library was compiled for Dalvik?
I would use 3 projects:
server
shared
client (android)
and include shared as a project dependency in both server and client. If you use ant you'd drop the shared.jar in both server/lib and client/lib every time it's changed, and if you use maven it's a dependency (possibly with Ant + Ivy it's also a dependency). Consider Nexus as a repository location in that case.
You don't actually need to create a separate Eclipse project for the shared classes. You can just create a 'common source folder' outside of the other two projects' disk hierarchy. For both the server and client projects :in the Properties/Java Build Path/Source add a 'Link source' to the new folder. (Perhaps this is what you meant by 'relative link'). It's easy to add this common source folder to an Ant build file.
You could add the path to the classes/JARs to the server's runtime classpath.
Since it's unclear which one you're using, here's just a generic answer based on Apache Tomcat.
Open /conf/catalina.properties file.
Edit shared.loader entry to include the path to the package root of those classes or JAR file(s).
E.g.
shared.loader = /path/to/classes
or
shared.loader = /path/to/specific.jar
or
shared.loader = /path/to/*.jar
You can even specify multiple paths separated by a comma.

Categories

Resources