I'm building a library that uses Spring 4.2.4 and am planning to bundle Spring with the library, to make a self sufficient jar with all dependencies included because some of my clients don't use Maven.
However, some of the clients using the library could be using a different version of Spring already in their applications, some as old as Spring 2.5. In this case, they would exclude the bundled version of Spring. Then how do I handle feature compatibility issues? For example, Spring 4 can have multiple PropertySources, and this is not supported in earlier versions.
Only if you really need to, you can bundle the libraries you want in your library and alter their packages to make sure that no collision or class loader conflicts happens in scenarios such as what you describe happens. If Maven is your build system, you could use the Shade plugin to accomplish this. Such an approach is taken in such popular libraries as Jersey 2 where the guava library classes are included in the distribution with modified package name.
Related
I am using ActiveMQ 5.16.0 downloaded from Apache. I see a few of the jars are older versions which have vulnerabilities, e.g.:
com.google.guava_guava 19.0
core_jackson-databind 2.9.10.4
shiro-core 1.5.3
log4j-1.2.17
I see all above vulnerable jars are located under apache-activemq-5.16.0\lib\optional\. What is use of jars under the optional directory? Is there any latest release of ActiveMQ which has all latest dependencies?
Optional dependencies are just that: Optional.
Using Shiro in your case as reference.
Optional Dependencies: Typically an optional dependency is not required for the core functionality of the library you are referencing. In this case, Shiro is only required if you intend to make use of Apache Shiro features or functionality. Shiro is used for security and therefore makes sense that it will not be used by everyone making use of ActiveMQ.
Versions: Many times (not always) optional dependency versions are not set in stone and it may be possible to use newer versions without breaking the functionality. This is not always the case, so if you aim to do this, start with the preferred version and only upgrade after the functionality is working to test.
Vulnerabilities: Simply because a vulnerability exists, does not make it applicable to your use case. Just because there is a known vulnerability in a dependency that can do XYZ, it will likely not affect you if your use case does not make use of XYZ. A security report such as the Apache Shiro one could help in understanding this.
Additionally: I would suggest that you look into Maven or Gradle for your Java projects. This will take away some of the need to worry about these types of dependency management issues as optional dependecies are not included in the dependecy hierarchy by default.
Trying to figure out how will the JVM decide which dependency to use:
We have a gradle compiled fatJar, containing several dependencies, i.e. Jackson X version etc.
My app is a Play framework 1.x app, using the the fatJar artifact from stage 1, and other dependencies, including aws java sdk which uses Jackson itself, newer than X version.
How can I tell which Jackson version is used in runtime?
[It seems that on 1 env it uses the correct one, and on the other, aws sdk is using the incorrect Jackson]
In simple case when you provide classpath to java and do not use any classloader the answer is simple. It will search classpath in order you provide.
I strongly discourage you from relying on that behavior.
There is solutions for you problem. One of them to use OSGi it allows to use multiple version of libraries, but i must mention that it is heavy framework.
I want to build a REST API using RestEasy. The generated file should be deployed in a WildFly application server.
I face the issue described in the following SO-question:
AsynchronousDispatcher error
The marked solution tells me, to set the dependency to "provided". Which as far as I understand means, that the library is not included in my war file but taken directly from the app-server...
Isn't that just wrong?
My idea would be to build a self-containing war file which contains all the needed libraries in the version I need.
When provided from the app-server I do get the currently available version from there. I have not really a clue about the version... when someone has the idea to update the RestEasy library on the server, it might break my app.
I'm not sure whether I missed something or did something completely wrong?
One of the big advantages to Java EE is developing towards the API and not having to worry about the implementation. Java EE containers provide the API's and implementations for the API's. If you include implementation dependencies one of two things is likely to happen.
You're dependencies will be ignored making it pointless to include them in your deployment.
You'll get conflicts between the dependencies you included vs what the server is expecting. This could be things like:
ClassCastException because it's finding two of the same class on the class path.
MethodNotFoundException because there is a version mismatch
Various other issues with conflcts
Developing towards the API instead of the implementation also allows you to easily switch between Java EE compliant containers with no to minimal changes to your deployment. The API's are generally backwards compatible as well making version upgrades not as big of an issue.
If you want to use a fat WAR (including implementations) instead of a skinny WAR (not including the implementations) then a servlet container is probably a better solution. WildFly does have a servlet only download. I'd encourage you though to trust container to do the right thing with the implementation dependencies :). Usually the only time there is an issue with upgrading is if you're upgrading Java EE versions. Even then it's usually pretty safe.
Is it possible to use a grails plugin outside of the grails framework?
Plugins that depend on Grails itself obviously don't qualify, but assuming a plugin depended only on non-grails libraries, is there a way to use a packaged plugin, as-is, in stand-alone groovy or Java app?
Intent
We have a LOT of functionality in Grails plugins, and we're thinking of using springboot for standalone groovy applications, so reusing the functionality in those plugins is important. I know Grails 3 is moving to springboot, but we're not holding our breath.
A packaged Grails plugin appears to contain only groovy source files, so I suspect this will work for groovy-based projects, though more difficult for pure Java projects.
I would guess the answer to this is "probably not" for the reason that your requirements specify something that shouldn't exist, but might. Why would a plugin be a plugin if it didn't require some measure of Grails libraries, processes, etc. If a plugin is just code, then it should really just be a jar.
That said, maybe there are plugins with just some Groovy classes in them. In that case, as long as you also manage to add their dependencies to your project, it shouldn't be that difficult to take the code for the plugin and convert it to compile into a jar instead, then depend on that jar (and its dependencies) in your project.
Be careful, as many plugins also depend heavily on Grails' Spring dependency injection. As you plan on using Spring Boot, that shouldn't be too difficult to recreate in your project, as the doWithSpring block in the plugin's descriptor should give you a good idea of what beans are needed. You should also look out for Grails-convention autowiring. If the plugin has a controller or service with a member named fileService, then you'll need to make sure that controller has a fileService injected when it's instantiated, just like Grails would do.
Finally, the directories in the plugin in which you find the classes in question are also important. Grails treats and loads classes from different directories in different ways (think Filters, Events, Jobs, etc.), which you would no longer get automatically. A plugin with some of these in it would take special handling when brought into a non-Grails project.
So, without knowing which plugins you're trying to use the classes out of, it's hard to say whether what you want is possible. I still think that most of the plugins people use actually require some Grails-like environment in which to run. That could be Grails, or something you set up that works similarly in Boot (good luck!)
I want to make a java application that supports plug ins. Now my core will use jars for certain processes. If my plug ins where to also use these jars, do the plug ins of my application need to configure their build path to include the jars they would also use or is their a way so that the jars can be imported similar to how I import packages from the main application
Guice and Spring are tools for dependency injection, which means that creating objects is easier with them because they take care of instantiating objects and placing them into other objects that depends on them.
Now, when we talk about plugins, we usually are talking too about dynamically loading new classes into a running app. Think on eclipse IDE. Its architecture was designed from the beginning to be "pluggable", like, you can download jars and eclipse will add them to the running application without the need of application restart.
In this case, if you want to build pluggable apps, in a sense of dynamic classloading, I'd recommend you not to go through this path, but to research subjects such as OSGI. One popular OSGI framework is http://felix.apache.org/
Another approach for application extension (we may call this pluggable too, somehow, I guess), depending on how your app is organized and what it does, is to develop a DSL (http://en.wikipedia.org/wiki/Domain-specific_language) for it and extend it letting people adding scripts to it. Isn't something like this when a browser let you add pieces of funcionality written in javascript? Groovy makes DSL easier in some aspects, for java programmers. (see http://docs.codehaus.org/display/GROOVY/Writing+Domain-Specific+Languages)
If you want dynamic plugable systems OSGI can give you this, but OSGI its IMMO a over-complicated technology, use only if you are really sure that needs this dynamic plug-ability.
Other option for builds extensible systems its use de ServiceProvider mechanism, this is a core java mechanism, for example its the one that JDBC implementations use, you can put a JDBC driver in your classpath and the application can find it and use it without needing that you explicitly import the driver classes in your code.
This is an example of using ServiceProvider in your owns applications: http://docs.oracle.com/javase/tutorial/ext/basics/spi.html#limitations-of-the-service-loader-api
Its of course more limited than OSGI, but its very easy to use when you get the idea, and you don't need any external library because its a java core mechanism.
EDIT: about the libraries.
In runtime: With ServiceProvicer there is no separate classloaders (you can implement off course, but by default, in OSGI its implemented this separation), in runtime if your plugin need X class and this class is in the classpath all is ok, the limitation its that the main application and all the plugins use this version of the dependency (guice 3 for example) and you cannot have one plugin using X version and other plugin using X+2 version if this version are not compatible. (this is the famous hell .jar, and one of the principal motivations behind jigsaw project for example).
In compile time, include the dependency in your pom, ant build file, gradle build file or whatever build system your use as usual.