Declare dependency to war file in Gradle - java

Based on the gradle docs, to define external jars means adding to build.gradle the following snippet (considering you have {project_root}/libs/foo.jar) in place:
dependencies {
runtime files('libs/foo.jar')
}
However, using the same dependency declaration for *.war files doesn't work. Is this even possible? The project I'm trying to depend on builds to a war file.

Since war layout is different from jar file standard layout, it's not possible to declare war a dependency file to a java project. Possible ideas:
Clone the project and define it as a dependency (very stupid idea, I'm ashamed that I suggest sth like that)
Contact the author and ask him/her if you can just copy the class you need to use. If you can copy the class along with the credits.
Contact the author and ask him/her if it does make sense to make the codec open source (I know it is right now) and release it as a standalone jar library (maybe along with other classes used in the project).

Related

How to enable Yandex Translate API?

this may sound like a noob question, but it is a big problem for me. I have a file called yandex-translator-java-api-master.zip, and I tried adding that as an external JAR to my eclipse project, but the code wouldn't work; It wouldn't let me import.
This error comes up when i try to import "Translate"
Translate cannot be resolved
6 quick fixes available:
Create class, create constant, fix proj. setup...etc, etc.
How do i use this??? Where is the .jar i am supposed to import?
zip archive is not the same thing as jar. First, extract jar from zip archive and then add it as dependency. Then you'll be able to import.
UPD:
looking closely, I suppose you downloaded that archive from GitHub (or another VCS) and it's just sources of a library. You can not add it as a dependency, but you can, for example, just paste this code in your project's /src/main/. This is an easy solution. If you want to make things the right way, you can
a) Search for a compiled library
b) Create a module from downloaded sources and add it as dependency
Download this file:
And established it as a library.
Instruction is in this answer.

Use JARs of linked projects instead of .class

I am building a desktop application with NetBeans 8.0.2. For my application, I have to manage 3 differents projects : The main project, and two "tool" projects that are linked to the main.
When I run the main project, it will check the JARs present in his classpath in order to retrieve the Manifest files and do some work with.
In order to have my application run correctly, it has to see the two linked projects' JARs but it doesn't, because NetBeans deals with the compiled classes of the project instead of the JAR (for debugging purposes I presume).
I found nothing about it on the Oracle documentation, and the only thing looking a bit like what I search is to create a big-fat-JAR by using another component.
Is there a way to tell NetBeans to "compile the linked projects and use the JARs instead of the .class" files ? Thanks in advance
EDIT : Here is an example when I add the project with "Add Project .." option
/C:/Users/xxxxx/Documents/GuiceProjectsRD/xxxReaderRef/build/classes/
And here is an example when I add the JAR
/C:/Users/xxxxx/Documents/JavaLib/xxxReaderRef.jar
When I add the JAR, I have the ".jar" extension which helps me identify a JAR and then look into it for a Manifest. When I add the Project, there is no path to the JAR but only to the compiled classes, and I can't work with that.
I would not depend on the Manifests in Jars since you then get this kind of issues.
Have a look at the Typesafe Config library. It's a small 100% pure Java library to work with Json/Hokon configuration.
Instead of relying on a Manifest, create a 'reference.conf' in each tool project. In your application, create an 'application.conf' (if needed). Load the config via 'ConfigFactory.load()'. It will automatically search all available reference.conf's, and application.conf, on the classpath, whether in a jar or not, and merge those configs into a single configuration.
I use this approach in project to be able to plugin extension. Have for example in tool A a configuration like
tool.A.class = 'my-tool-A.class'
or used nested structures like
tool {
A {
class = 'my-tool-A.class'
}
}
Do something similar voor tool B.
Then in your application, from the Config, you can get a list of 'tool' configs and detect the available tools like that.

MANIFEST.MF file for JAR Used in Web App?

I've developed a utility library that will be used in many of our enterprise Java applications. This library has numerous additional dependencies that also need to be on the classpath. I'd like to avoid forcing our developers to add a zillion entries to their MANIFEST.MF files, and let them instead just include my library. Is there any way that my library's MANIFEST.MF file can reference its dependencies and have them picked up by the enterprise applications that will be using my library?
I've tried referencing them in my library's MANIFEST.MF file using the full path to the dependencies on the filesystem. That didn't work. I end up with ClassNotFoundException errors for all of my dependencies. Is there something else I should be trying?
When you create a web application, you'd normally put it in a WAR file. The idea is that you bundle the required dependencies in that WAR file, by adding the jars to the /WEB-INF/lib folder inside the WAR. Web containers (like in a Java EE application server) know of this structure and will include those jars on the classpath.
If your library has additional dependencies, just tell the users about it and either redistribute them with your library if the license allows it, or tell them where to obtain them. When using a decent tool for creating a web app like an IDE, Ant with Ivy, or Maven (or a combination of these), then handling and bundling dependencies should be no problem.
Alternatively, this works so long as you stick to the format very carefully, i.e. stick to exactly two spaces before each "file:" etc:
Manifest-Version: 1.0
Main-Class: package.TestClass
Class-Path: file:/D:/WebServer/Tomcat/shared/lib/BlueCove.jar
file:/D:/WebServer/Tomcat/shared/lib/classes12.jar
file:/D:/WebServer/Tomcat/shared/lib/comm.jar
file:/D:/WebServer/Tomcat/shared/lib/FTP.jar
file:/D:/WebServer/Tomcat/shared/lib/FTP2.jar
file:/D:/WebServer/Tomcat/shared/lib/iText.jar
file:/D:/WebServer/Tomcat/shared/lib/j2ee.jar
file:/D:/WebServer/Tomcat/shared/lib/jmxremote.jar
file:/D:/WebServer/Tomcat/shared/lib/jmxri.jar
file:/D:/WebServer/Tomcat/shared/lib/jmxtools.jar
file:/D:/WebServer/Tomcat/shared/lib/jpos15.jar
file:/D:/WebServer/Tomcat/shared/lib/js.jar
file:/D:/WebServer/Tomcat/shared/lib/mail.jar
...
file:/C:/WebServer/Tomcat/shared/lib/soap.jar
file:/C:/WebServer/Tomcat/shared/lib/sqljdbc.jar
file:/C:/WebServer/Tomcat/shared/lib/tools.jar
I've done this with a number of tools. It is a truly horrible hack but seems to work reliably.
Give them a special manifest to use. Something like:
Manifest-Version: 1.0
Main-Class: com.xxx.yyy.zzz.YourSpecialClassThatHacksTheClassPath
Real-Main-Class: com.ppp.qqq.TheirMainClass
In your special class, screw around with the classpath (not easy), read the manifest "Real-Main-Class" entry (a bit easier) and launch their main from that (not really difficult at all).
Obviously this will not work with a .war file.
Even I had the same problem. As mentioned above, the solution was to have exact two space after file:/ and one space after .jar file and at the end, press enter key.
I know this is not a neat solution, but it works. enjoy.

Managing Data Dependecies of Java Classes that Load Data from the Classpath at Runtime

What is the simplest way to manage dependencies of Java classes to data files present in the classpath?
More specifically:
How should data dependencies be annotated? Perhaps using Java annotations (e.g., #Data)? Or rather some build entries in a build script or a properties file? Is there build tool that integrates and evaluates such information (Ant, Scons, ...)? Do you have examples?
Consider the following scenario:
A few lines of Ant create a Jar from my sources that includes everything found on the classpath. Then jarjar is used to remove all .class files that are not necessary to execute, say, class Foo. The problem is that all the data files that class Bar depends upon are still there in the Jar. The ideal deployment script, however, would recognize that the data files on which only class Bar depends can be removed while data files on which class Foo depends must be retained.
Any hints?
This is one of the many problems Maven has already solved with it's build, dependency, and resource management. Any maven project follows a standard directory layout which dictates where you should put your Data files: in the 'resources' directories. The conventional Maven directory structure is as follows...
/
/src/
/src/main/java/
/src/main/java/App.java
/src/main/resources/
/src/main/resources/my.prod.data.or.cfg.or.whatever
/src/test/java/
/src/test/java/AppTest.java
/src/test/resources/
/src/test/resources/my.test.data.or.cfg.or.whatever
/pom.xml
The benefit of this is that all files which are contained in the 'main' (prod) resources directories are available to your application at run-time from the Classpath. All of the 'test/resources' files are available to your code during build & unit test time but are NOT included in your final artifact.
I don't think a generic solution exists for the system you describe, however, I just had a stab at reading annotations on classes using ASM, since that is used by jarjar as well. It is not hard to read the annotation data that way (pass in a ClassVisitor to the accept() method on ClassReader, and do something useful on the visitAnnotation callback). This means you can either try and include your intended behavior to jarjar or you could add it as a custom step to your build process.
Can't you refactor your project so that you have submodules that each contain the relevant files for the project itself ; Bar class and Bar related files will be packaged in their bundle while Foo ones will packed into another?
Another possibility would be to use some package naming convention to be able to filter the files you want to see i your bundles.

Java distribuion as jar file containg config, libs and deps

I am developing a framework that needs a lot of stuff to get working. I have several folders inside of my Eclipse project that are needed
[root]
- config
- src
- lib
- serialized
Also there are important files like the log4j.properties and the META-INF dir inside the src directory.
I wonder if there is a way to distribute one JAR containing all essential files so my gui will just have to import one jar. I guess that I have to exclude the config folder in order to make the framework configurable.
I also wonder, if there is a way to move for example the log4j.properties to the config dir so that I have one config folder containg all needed configurations?
Thanks for help and advise on this matter!
Marco
Yes, but not really. You can take all your dependencies, unpack them and simply merge them into a bigger jar. This is what the maven jar plugin does if you make a jar with dependencies. The only problem is that this might result in conflicting files (suppose two of your dependencies contain a log4j.properties). This is one of the problems when doing the above with some of the spring libraries for instance.
I think someone actually wrote a classloader that allows you to bundle the whole jar inside of your jar and use it as is. I'm not sure how mature that is though and can't at the moment recall the name.
I think you're better off distributing all your dependencies separately. Setting up the classpath is a bit of a pain but surely java programmers are used to it by now. You can add dependencies to the Class-Path header in your manifest file, in simple cases. Bigger libraries have to rely on the classpath being set up for them though.
As to the second part of your question, probably dropping the conf/ directory under META-INF is enough for its contents to be picked up. I'm not sure about this. I'm fairly sure it will always be picked up if you put its contents at the top level of the jar. In any case, this is a distribution problem. You can easily have a conf/ directory inside your source tree and have your build scripts (whatever you might be using) copy the files in it to wherever is most convenient.
As to your users configuring. Try to establish some conventions so they have to configure as little as possible. For things that must be configured, it's best to have a basic default configuration and then allow the user to override and add options through his/her own configuration file.
In terms of the resources, it is possible except that if you do that you are not going to be able to load resources (non class files) from the filesystem (via a file path).
It's likely that you're currently loading these resources from the file system. Once in the jar you need to load them as class path resources via the class.getResourceAsStream or similar.
As for the dependent jars you may have, it's common practice for these to be placed as extra jars on the classpath. I know it's complicates things but developers are used to doing this. The nature of the java landscape is that this is inevitable. What the spring framework for example does is supply a bundled zip file with the core jar and the jar dependencies included.
Is your library going to be used in an EE context or an SE context? If it is an EE context then you really don't have to worry about configuration and class path issues as the container takes care of that. In an SE context it is a lot more tricky as that work has to be done manually.

Categories