How can symlink affect loading persistence.xml - linux

In my project there're two different persistence.xml appearing in two different jar files after building. If I run application using command like this
/jre/v1.7.0_21/bin/java -cp patch:/path_to_app_jars/*:. org.somepath.MainClass
one of them is loaded but if I run it using symlink another one is peaked up
bin/ -> path_to_app_jars
/jre/v1.7.0_21/bin/java -cp patch:/bin/*:. org.somepath.MainClass
And this result is consistent regardless of what else I change.
How could that be?

My guess is that the expanded jars are returned in a different order when using the symlink, and it is loading the persistence.xml from the first jar listed.
As described in the java documentation, the order in which the jar files are returned when using a directory wildcard (*) is unpredictable. In order to always have the same jar loaded first, the solution is to list the jars explicitly in the classpath instead of using a directory wildcard:
The order in which the JAR files in a directory are enumerated in the
expanded class path is not specified and may vary from platform to
platform and even from moment to moment on the same machine. A
well-constructed application should not depend upon any particular
order. If a specific order is required then the JAR files can be
enumerated explicitly in the class path.

Related

How to make a GDSL file in a jar get picked up in another project in Intellij?

I have a project with a GDSL file that describes a DSL delegate like:
def ctx = context pathRegexp: ".*installer\\.groovy", scope: scriptScope()
contributor(ctx) {
delegatesTo(findClass("com.whatever.InstallerBase"))
}
I package this file up in the jar (just in the root of the jar) using maven.
In a separate project I have a maven dependency on my jar artifact containing the gdsl. However, my autocompletion doesn't work. It works fine with the sample scripts in the first project (with the GDSL).
Is there a step that I'm missing in order for the GDSL to be picked up? Do I need to place it in a special folder in the jar?
The problem was indeed what #PeterGromov indicated in the comment on the question:
ensure that the library jar is only attached as classes and not library source as well
both the source and library were configured and thus IDEA doesn't include it. I have opened a youtrack issue to fix this here:
https://youtrack.jetbrains.com/issue/IDEA-137411

Is there a way to prevent IntelliJ IDEA from compiling logback.groovy?

I have a groovy project in IntelliJ IDEA that uses logback.groovy. It's in src/main/resources so that it ends up in the classpath of the project, but IDEA compiles it into logback.class. Logback expects this to be in .groovy format, so this won't do. Is there a way to prevent this behavior? I just want logback.groovy in my classpath for running unit tests and webapp debugging.
IDEA 13 now supports new types of directory assignments under your content root: the relevant one for this question is "resources".
In previous versions, IDEA only supported marking directories as "sources" or "tests".
So the new correct answer is to mark src/main/resources directory as a resources folder of your content root. By marking the contents of a directory as "resources", you're telling IDEA that the contents are not source code but need to be accessible on the classpath at runtime.
[Added as a separate answer because the first one is still potentially useful if your file is stuck under your source tree for whatever reason - feel free to merge it in to the other answer if that's more appropriate.]
I guess /src/main/resources is marked in IDEA as a source root? That's pretty much explicitly telling IDEA "the stuff under this directory is source files".
You could try adding the file to /Settings/Project Settings/Compiler/Excludes - but that will probably mean that your file won't get copied onto your output path (and thus won't be on the runtime classpath so logback won't see it).
My personal solution is that my logback.groovy sits outside of my /src tree - I consider it to be configuration rather than a source/resource file. My config directory itself is then added to the runtime classpath directly via /Project Structure/Modules//Dependencies (marked as runtime scope).
My solution was to modify the artifact to explicitly include logback.groovy in the WEB-INF/classes directory. It isn't ideal since this file could only be referenced by the absolute path and not as a project file, so any suggestions are still welcome.
I put logback.groovy in src/main/resources and added it to Resources patterns in IDEA's Compiler settings (ctrl + alt + s; Compiler > Resource patterns). And it works :)

Create a FAT source-only jar using Gradle

I need to create a jar that includes dependencies (a FAT jar) using Gradle.
The catch: the jar needs to only include the straight .groovy files... no .class files.
I've seen the way to do it from the Gradle cookbook: http://docs.codehaus.org/display/GRADLE/Cookbook#Cookbook-Creatingafatjar
and the One-Jar plugin:
https://github.com/rholder/gradle-one-jar
but both ways involved using the compiled .class files instead of the actual source .groovy files. Also, I don't need this jar to be runnable. I just need to be able to reference my .groovy scripts and have the dependencies already be there for them.
Is this possible?
I'm not sure if you even need a .jar file, or a .zip would suffice as it would be confusing to distribute source in a .jar. But independently of what you need, the Zip task is what you want:
task('fatJar', type: Zip) {
extension = 'jar' // overriding default value: 'zip'
classifier = 'fat' // alternatively you can set basename or appending
from(sourceSets.main.allGroovy) // will fail if the groovy plugin isn't applied
from(configurations.runtime) // this includes all your jars needed on runtime
}
Now this is an extremely simple example which will create a file called [projectName]-[version]-fat.jar within build/distributions/ with all your jars in the root of the zip and the groovy source files next to them. You might want to take a look at the documentation of the Gradle Zip task for more options.

Runnable jar with Apache POI

I'm trying to export my program as a runnable jar, packing the necessary libraries (Apache POI). The .jar is created, but it doesn't work. Is there a catch on deploying with these libraries? Because the program itself runs great from eclipse.
A few questions to ask yourself in this situation:
Where does the program fail? Are there any errors in the console? Are you running from the command line (java -jar myJAR.jar) so that you can see console output?
Okay, so you get a NullPointerException for the read file. Is the read file inside the JAR, or where is it? How does the program know where the read file is?
Is there really a problem with the way the JAR is packaged, or is it the way your code locates and reads in the file? Perhaps your code assumes a relative location which cannot be resolved when run from the JAR.
There are the following strategies.
Create your jar. Put it to chosen directory. Put there all dependencies of your application. Create script (shell script, batch file etc depending on your platform) where the java command line is either written hard coded or is generated. The line must include the class path, e.g.
java -cp myapp.jar;poi.jar com.company.MyMain
Create indeed runnable jar, i.e. jar that can be executed using command like java -jar myapp.jar. If your application has dependencies this jar must have MANIFEEST.MF file that defines class path using property Class-Path
Pack all your classes and all your dependencies into one large jar file.
Obviously all these operations should be automated either home made script or by one of available build tools.

Using Bouncy Castle library causes massive increase in output .jar file size

I'm working on a Java ME/J2ME project which makes use of the Bouncy Castle J2ME library. When adding it to my project, however, I've noticed the resulting .jar file size increases 40 times (50kB vs. 2000kB). Other than setting ProGuard's obfuscator settings to level 9 (max), is there any other way I can minimize this increase in file size?
I'm only using a few of the libraries actual classes, namely:
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.crypto.digests.SHA256Digest;
Thanks in advance.
Now this is a very tricky one!
Before anything else please can you unzip your jar file and see if the Proguard has obfuscated the class files of BouncyCastle? Since you have included bouncycastle jar file as a library and there are class files in it so I am assuming the Proguard hasn't obfuscated these class files which are taking much of the space.
Anyways I have just downloaded the bouncy castle jar file and can see it is purely made up of class files, so there are no extra files which we might be able to delete and get rid of to reduce the resultant jar file.
Now If you really want to reduce then read on I am going to produce two solutions, both of them are risky:
Solution 1 (Not Recommended):
This is easy but I wouldn't recommend, It may cause runtime exceptions or errors:
Unzip the bouncycastle jar file. Then navigate to the directory src\org\bouncycastle
As you have mentioned you are only using these below packages
org.bouncycastle.util.*
org.bouncycastle.crypto.*
Now here I will be assuming that the source code inside these two packages is not dependant on the source code/class files inside other packages.
Now delete the other directories namely "asn1", "bcpg". At this stage I will not become a butcher and delete everything but will go by deleting a couple and then come back and delete others if it worked.
Now we will regenerate the jar file. After you have deleted the directories now go back to the root of the directory where you will see other directories like
META-INF
org
utils
This is an important step you need to this correctly otherwise jar file will not work. Select all the directories in the root directory and
then right click-> send to zip
Once the zip file is created then rename it to having *.jar instead of *.zip
The size of the jar file would have reduced and now include this jar file in your project. See if it compiles and executes. Then check
your functionality if it is working correctly at Runtime. If all goes fine, then you are done.
Now you can repeat from above steps to delete further directories to reduce the jar file size.
Solution 2:
Download the source code of the bouncycastle jar file that you are using.
You will have to remove the jar file from the project.
Include the source code into the project. Build the project and see if you dont get any compilation error. You have to be sure at this stage
that you are not using the original jar file, and only using the code.
Now start deleting the packages containing code that you dont need. Keep rebuilding the project that it doesn't come up compilation error,
and if it does then you dont want to delte that package and move on deleting others.
Once this butchring is done then Build the project and generate the jar file.
By this way the Proguard will obfuscate code of bouncy castle and because of deleting most of the code not needed you should get a substantial
decrease in the resultant jar file.

Resources