How to find the path of a running jar file - linux

I'm trying to programmatically find the full path of a jar file while it's running. I know there are a number of other questions about this, but none of them seem to work for me - most notably, I've stumbled across
MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().gĀ­etPath()
a number of times. That particular method works for me when debugging in Eclipse, but once I compile to a jar, it returns a NullPointerException. Other methods have met similar problems after compiling.
I have a temporary workaround by using java.class.path, but that only returns the full path when I execute the jar from the GUI - in the terminal, it fails.
I should also note that the only system that I'm having this problem on is Linux. On Windows and Mac, I have no troubles.
Any help would be appreciated :)
Thanks!
Derek
EDIT: The jar is executable, if that changes anything.

You can't do it. There is no requirement for ClassLoaders to support this, and most don't.
Or, perhaps this formulation would be more helpful. Binary classes come into the JVM via ClassLoader objects. ClassLoader objects are not required to keep any track of the provenance of the classes they load. And they can load them from anywhere: a jar, over the web, a database, an old tin can.
So, if you want to always know the provenance of classes in your application, you have to always load code with a class loader that, indeed, does track provenance in a manner useful to you.
If you control the entire application, you can do that.
If you don't control the entire application, and are rather talking about an arbitrary jar loaded into an arbitrary class loader in an arbitrary app, you can't depend on learning its location.

The following works for me even when running from a jar file:
URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation();
String p = URLDecoder.decode(url.getFile(), "UTF-8");
File jarFile = new File(p);
Sending the path through the URLDecoder is important because otherwise a pathname with %20 in it will be created if the directory contains spaces.

Related

Why Is Doppl Trying To Pull in ReactiveStreams?

I am attempting to convert parts of an Android app to iOS using Doppl, and I am getting a strange result: Doppl keeps trying to pull in android.arch.lifecycle:reactivestreams, even though I don't want it to.
Specifically, in app/build/j2objcSrcGenMain/android/arch/lifecycle/, there is a reactivestrams/ subdirectory with R.h and R.m files in it. This seems to make Xcode cranky and may explain why I had some oddities with pod install.
My app/build.gradle has compile "android.arch.lifecycle:reactivestreams:$archVer", because my activity is using LiveDataReactiveStreams.fromPublisher(). However:
The activity is not in the translatePattern (and since its code is not showing up in app/build/j2objcSrcGenMain/, I have to assume that the translatePattern is fine)
I do not have a doppl statement related to reactivestreams, because there does not appear to be a Doppl conversion of this library (nor should it be needed here)
AFAIK, nowhere else in this app am I referring to LiveDataReactiveStreams, which AFAIK is the one-and-only public class from the reactivestreams library
So, the questions:
What determines whether Doppl creates R.h and R.m files for some dependency? It's not the existence of a doppl statement, as I have doppl statements for a lot of other dependencies (RxJava, RxAndroid, Retrofit) and those do not get R.h and R.m files. It's not whether the dependency is referenced from generated code, as my repository definitely uses RxJava and Retrofit, yet there are no R files for those.
How can I figure out why Doppl generates R.h and R.m for reactivestreams?
Once I get this cleared up... do I re-run pod install, or is there some other pod command to refresh an existing pod with a new implementation?
Look into 'app/build/generated/source/r/debug' and confirm there's an R.java being created for the architecture component. It'll be under 'android/arch/lifecycle/reactivestrams'.
I think there are 2 problems here.
Problem 1
Somehow Doppl/J2objc is of the opinion that this file should be transpiled. It could be either that 'translatePattern' matches with it, or that something in the shared code is referencing it. If you can't figure out which, please post a comment and I'll try to help (or post in slack group).
Problem 2
Regardless of why that 'R.java' is being sucked into the translate step, because of how stock J2objc is configured, the code is being generated with package folders instead of creating One Big Name. That generated file should be called 'AndroidArchLifecycleReactivestramsR.h' (and AndroidArchLifecycleReactivestramsR.m). Xcode really doesn't like package folders. That's why there's a slightly custom J2ojbc being used with Doppl, so we can have files with big names instead of folders.
In cases where you intentionally use package names that match with what J2objc considers to be "system" classes, you need to provide a header mapping file to force long names. The 'androidbase' doppl library needs to add a lot of files that are in the 'android' package, which J2objc considers "system". We override those names in the mapping file.
build.gradle
https://github.com/doppllib/core-doppl/blob/master/androidbase/build.gradle#L19
mapping file
https://github.com/doppllib/core-doppl/blob/master/androidbase/src/main/java/androidbase.mappings
I screwed up.
In my dopplConfig, I have:
translatePattern {
include '**/api/**'
include '**/arch/**'
include '**/RepositoryTest.java'
}
In this case, **/arch/** not only matches my arch package, but also the arch package from the Architecture Components.
Ordinarily, this would not matter, because the Architecture Components source code is not in my project. But, R.java gets generated, due to resources, and the translatePattern includes generated source code in addition to lovingly hand-crafted source code. So, that's where my extraneous Objective-C was coming from.
Many thanks to Kevin Galligan for his assistance with this, out on the #newbiehelp Doppl Slack channel!

Scons command/explicit dependency

I have a code snippet similar to this:
# Compile protobuf headers
env.Protoc(...)
# Move headers to 'include' (compiled via protobuf)
env.Command([include headers...], [headers...], move_func)
# Compile program (depends on 'include' files)
out2 = SConscript('src/SConscript')
Depends(out2, [include headers...])
Basically, I have Protoc() compiling protobuf files, then the headers are moved to the 'include' directory by env.Command() and finally the program is compiled through a SConscript file in the 'src'.
Since these are header files that are being moved (that the src compilation depends on), they are not explicitly defined as a dependency by scons (as far as I understand). Thus, the compilation runs, but the header files haven't been moved so it fails. I have tried exposing the dependency via Depends() and Requires() without success.
I understand that in the usual case, scons should "figure-out" dependencies, but I don't know how it could do that here.
Thanks!
You seem to be thinking in "make" ways about your build process, which is the wrong approach when using SCons. You can't order single build steps by putting them in different SConscripts, and then including those in a special order. You have to define proper dependencies between your actual sources (C/CPP files for example) and a target like a program or PDF file. Then SCons is able to figure out the correct build order, and will traverse through the folder structure of your project automatically. If required, it will enter subfolders more than once when the dependency graph (DAG) dictates this. Defining this kind of dependencies between inputs and outputs is usually done, using a Builder...and in your case the Install() builder would be a good fit. Please also regard the hints for #2 in the list of "most frequently-asked FAQs" ( https://bitbucket.org/scons/scons/wiki/FrequentlyAskedQuestions).
Further, I can only recommend to read a little more in the UserGuide ( http://www.scons.org/doc/production/HTML/scons-user.html ) to get a better feeling for how to do things in a more "SConsy" way. If you get stuck, feel free to ask further questions on our mailing list at scons-users#scons.org (see http://www.scons.org/lists.php ).
Finally, if you have a lot of steps that you want to execute in serial, and that don't require any special input/output files, SCons is probably not the right tool for your current task. It's designed as a file-oriented build system with automatic parallelization in mind, a simple (Python?) script might be better at the mere serial stuff...

Give an example of: groovyc --sourcepath

I am unable to get the --sourcepath option of groovyc to work at all. Can someone furnish a trivial example of it actually doing anything?
Ultimately I want to use "groovyc" at the command line with a directory a packaged organized tree of mixed groovy and java source. I don't want to reference each source file explicitly. And I don't want to use an ant or maven task either, on grounds of both principle (hey is there a bug here?) and because the production scenario that I might want to tweak the source in has neither but will have groovy. I know I could use unix find but must I resort to that?!
sourcepath isn't used anymore. It's only there for backwards compatibility and will be removed in the future.
The Groovy documentation is currently rewritten, you can find a snapshot including the documentation for groovyc here: https://dl.dropboxusercontent.com/u/20288797/groovy-documentation/index.html#ThegroovycAntTask-groovyc

Groovy Source Code Question

Today i decided to see up Groovy source code and to built up my programming muscles in Groovy. I downloaded the Groovy Source code 1.8 from this link. But how do i proceed? In sense which folder first i have to see, so that i can understand better how groovy works(because there are many folders like benchmarks,bootstraps, src etc). May be this seems to be stupid question but i wanna to ask it.
Correct me if am worng.
The source code is inside src/main.
The unit tests all live inside src/test.
I found a good place to start looking was inside the huge class:
src/main/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
This is where a lot of the extra Groovy methods are defined, so you can pick your favourite function (such as String.capitalize for example) and find the definition of that method (around line 9561, but that might be different in the version of the code you have downloaded)
You should then be able to (for example) change how something works, and check that the unit tests still function by calling
ant test
from the root folder, then you should see it build and test reports should be created and placed in the target folder
I tend to use a combination of find and grep to locate the area in the source that I am interested in, then slowly expand out from that class as I find other things that relate to it...
Hope this helps...it's a bit of a big question to try and cover

how to distribute a Flash component for use with MTASC?

I have a Flash component that's just a library of compiled code with some exposed API calls. Normally we distribute this as a SWC or MXP, and it works just fine. Recently I had a client express interest in using my component, but they do all their development in MTASC only. MTASC doesn't support SWC files, so ss there a good way to send precompiled code that would work in MTASC? I'm not able to send them the original source code, but if there's some other method I'd appreciate it. I do have access to the source, so I can recompile it however necessary. Thanks!
I did find an answer, and I'm not 100% sure if this is exactly the process since I'm no longer at that job and don't have the computer/process in front of me anymore. It was a bit of a hack.
What it involved basically was unzipping the SWC file and getting a .swf and a bunch of .asi files out.
The .asi files are really just ActionScript files, but they contain intrinsic definitions, or just prototypes or footprints of whats actually there. The real meat of it is still in the .swf.
So you rename all those .asi files to .as and then put them into your MTASC classpath. Since they contain definitions, you shouldn't be getting any more "undefined variable" or "undefined function" errors at compile time. Now you just need to pull in the SWF, where the actual function bodies are defined, using loadMovie. once the loadMovie is complete, you should be able to use all of the functions.
The only caveat of course is that you have to wait for that SWF to load before calling of any of the functions from the SWC.
so step-by-step, it looks like this:
1.) unzip the SWC file. this can be done using WinZip or OS X terminal unzip command
2.) Rename .asi files to .as
3.) add new .as files to MTASC classpath
4.) add AS code to load the .swf in and make sure none of the SWC functions are called before the SWF is loaded
5.) compile
I'm pretty sure this is what we did, but i'm not in a spot to try it out right now.,
Hope this helps, let me know if you have any other questions and I'll see if I can help figure it out any more.

Resources