How to get the eclipse installation/plugins directory or path - eclipse

How to get the Eclipse installation directory through programming in swt/java.
I actually want to get the plugins directory of the eclipse.

Update (January 2012)
James Moore mentions in the comments that the FAQ and API are quite old.
FileLocator.resolve(URL) is now preferred to the deprecated Platform.resolve().
As this example shows, you need to pass the actual resource (here a bundle), not the name of the resource, in order to resolve it:
private static URI locateFile(String bundle, String fullPath) {
try {
URL url = FileLocator.find(Platform.getBundle(bundle), new Path(fullPath), null);
if(url != null)
return FileLocator.resolve(url).toURI();
} catch (Exception e) {}
return null;
}
}
See also "How to refer a file from jar file in eclipse plugin" for more.
Original answer (January 2011)
Maybe the FAQ "How do I find out the install location of a plug-in?" can help here:
You should generally avoid making assumptions about the location of a plug-in at runtime.
To find resources, such as images, that are stored in your plug-in’s install directory, you can use URLs provided by the Platform class. These URLs use a special Eclipse Platform protocol, but if you are using them only to read files, it does not matter.
In Eclipse 3.1 and earlier, the following snippet opens an input stream on a file called sample.gif located in a subdirectory, called icons, of a plug-in’s install directory:
Bundle bundle = Platform.getBundle(yourPluginId);
Path path = new Path("icons/sample.gif");
URL fileURL = Platform.find(bundle, path);
InputStream in = fileURL.openStream();
If you need to know the file system location of a plug-in, you need to use Platform.resolve(URL). This method converts a platform URL to a standard URL protocol, such as HyperText Transfer Protocol (HTTP), or file.
Note that the Eclipse Platform does not specify that plug-ins must exist in the local file system, so you cannot rely on this method’s returning a file system URL under all circumstances in the future.
In Eclipse 3.2, the preferred method seems to be:
Bundle bundle = Platform.getBundle(yourPluginId);
Path path = new Path("icons/sample.gif");
URL fileURL = FileLocator.find(bundle, path, null);
InputStream in = fileURL.openStream();

Use the below code to get the plugin path :
this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

Related

How to read the .xml file path in Eclipse rcp application using java?

I have find the solution.This solution will help me to read file from appropriate folder path.
**
String resourceFolder=""; URL url=new
URL("platform:/plugin/com.example"+resourceFolder);
String resourceFolderPath=org.eclipse.core.runtime.FileLocator.toFileURL(url).getPath();
resourceFile=resourceFolderPath+"xxxx.xml";
**
Is there any other way to find it?
FileLocator is the correct API to use to access plugin resources.
Use FileLocator.find to get a URL to a resource:
URL url = FileLocator.find(bundle, new Path("relative path in plugin"), null);
bundle is the Bundle for the plugin. For the current plugin you can get this using:
Bundle bundle = FrameworkUtil.getBundle(getClass());
to get the bundle of a different plugin use:
Bundle bundle = Platform.getBundle("plugin id");
The URL returned by find is an bundleentry URL. You can use openStream on this to read to resource.
If you want a file URL you can convert the url using:
URL fileURL = FileLocator.toFileURL(url);
This may cause Eclipse to copy the resource in to a file in a temporary location.

After creating a File, how do I make sure it getting downloaded to the default download folder?

I'm trying out #tototoshi's scala-csv library and its very simple, looks like this:
def downloadFile = Action {
val f = new File("out.csv")
val writer = CSVWriter.open(f)
writer.writeAll(List(List("a", "b", "c"), List("d", "e", "f")))
writer.close()
Ok.sendFile(f, inline = false, _ => f.getName)
}
but now I the file is getting download to my project directory:
and I want it to get downloaded to the default download folder of whoever use this func, how can I do this?
the file is getting download to my project directory
This has nothing to do with Scala or with scala-csv, it's just the way new File(String) constructor works: if you pass a relative path like "out.csv" (or more generally, "directory/directory/..."), it uses the working directory, which is set by the "run configuration" when running in IDEA. Use an absolute path ("C:/directory/..." on Windows or "/directory/..." on Linux/Mac) instead.
to the default download folder
There is no built-in way to find default download folder in Java, it depends on the OS. See General Path To Downloads Folder for an answer for Windows.
You'll need to resolve the download folder yourself. The library will, given a path, write a CSV to that path. It'll include other CSV facilities, but definitely not path resolving code.
To the best of my knowledge, there's no one environment variable that will point to default "Downloads" directories...
If you're on *nix, typically downloads are in ~/Downloads, so your path will be "~/Downloads".replace("~", System.getProperty("user.home")). This can then be passed into java.io.File's constructor.
I don't know Windows' filesystem well enough to tell you if this will work for Windows as well, but a cursory search suggests it should work, too.

Why NuGet adds app.config with assemblyBinding to LIBRARY projects during a NuGet package update?

Isn't this information necessary only in the executable's project?
How to disable this file creation?
NuGet 2.8
EDIT
Library projects were exceptions in NuGet 2.7, behavior changed in 2.8 by fixing this issue: http://nuget.codeplex.com/workitem/3827 with commit: https://github.com/NuGet/NuGet2/commit/448652d028e3f01ba4022e147baaf4e1fb3f969b
The reason that the NuGet package manager adds assembly binding redirects to library projects is because there are types of projects where the output type is a library, but there are special mechanisms in place to assure that the library's app or web config file will be applied at runtime. This is opposed to more typical library usage that you're probably familiar with, wherein the library's config file is not used at all.
For example, Azure Web and Worker role projects in Azure SDK 1.8+ will produce libraries, but when they are wrapped in an exe by IIS, the library's config file will be set as the default for that exe. That way you get all your application configuration without having to explicitly publish a special config file with the same name as the wrapping executable, which is how it used to be done. Now the build process outputs the renamed config file (e.g. app.config -> myWebRoleLibrary.dll.config), and everything works as it should.
XUnit also does something similar; loading the app.config of the test assembly instead of the app config of the test runner process.
It's worth mentioning that you can also manually load a config file in any project, library or not. You would have to ensure that the config file ended up in the right place, but it is possible. This is less applicable for binding redirects though, since usually those are solely used by the assembly loader in the CLR. I suppose you could hook AssemblyLoad but now we're well on our way to poorly reinventing the wheel.
So, the answer to "is it necessary in my library project?" is maybe. If your library project is not a web or worker role or test project, and it doesn't manually load a configuration file, then the app.config is probably benign but unnecessary.
As for disabling it, you can only do that at the Visual Studio level. You can find the option in VS2019 at: Tools -> Options... -> NuGet Package Manager -> General -> Skip applying binding redirects.
What uses my configuration files?
The Compiler (csc.exe)
The compiler uses the config file of the assembly being built for one reason: to find and use supportPortability elements.
The link above lays out rare scenario where you would need that compiler option, but an overwhelming majority of users will not. Suffice it to say, if you don't know if you're using that feature, you are not.
It does not parse any of the other elements of the config file, including assembly binding redirects which are the elements that NuGet adds.
The Build Engine (msbuild)
MSBuild uses app configs in a few of its steps but importantly not to find the primary dependencies, which it will pass to csc.exe in the form of /reference: options.
In order to find the primary references MSBuild (and specifically the ResolveAssemblyReference task) will search a collection of paths enumerated in the common targets file. If it cannot find an explicit dependency in your csproj, it will issue a warning and likely an error further on if the dependency is required for compilation.
After that it will search for transitive dependencies. It does not pass these files to the compiler, but instead uses them to generate a list of files that need to be considered in subsequent build steps for things like generating license files, trust information, and suggested binding redirects. This step does consider the project's config file, and specifically uses its binding redirects to inform the list of transitive dependencies. It's important to note that building an exe will not consider its library's app.config files during the build, and a library's app.config will not change the way that library’s dll is produced.
The Runtime (CLR)
The CLR uses the config files to change the way it locates assemblies.
IIS
IIS will read elements of your web.config file to change the way your web app behaves. For example, caching characteristics.
Applications
Applications may manually retrieve configuration data from config files using the ConfigurationManager.
Assembly binding redirects are as valid in a class library as they are in executable projects.
Think about this; when building your application, how will the compiler know which version of referenced assemblies to use (for the class libraries)?
Often this will work just fine, without the redirects, but when you stumble over a machine that has a GAC'ed version of the assembly, you could get into trouble.
I suggest you read the assembly binding redirect documentation to better understand what it is and does.
NuGet adds the app.config with redirects to help you, and quite frankly, I don't get the fuzz about an extra app.config for everything to work as expected.
As of today, it will add redirects to all projects, except the following types:
WiX
JS
Nemerle
C++
Synergex
Visual Studio
Windows Store App
As far as I know, there's no way of turning this off. You could create an issue at Github if this is a problem.
The source code for adding assembly binding redirects can be found here.
I created a little console app that checks all the date of the app.config files and then auto deletes them from your .csproj and the file. Todo: delete from tfs.
Perhaps this could help.
class Program
{
private static string RootFolder;
private static string AppConfigName;
private static bool AskConfirmation = true;
static void Main(string[] args)
{
try
{
AppConfigName = "app.config";
RootFolder = #"<Your project path>";
ScanDir(RootFolder);
Console.WriteLine();
Console.WriteLine("DONE!");
Console.WriteLine("Press ENTER to finish...");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static void ScanDir(string directoryParent)
{
var dirs = Directory.GetDirectories(directoryParent);
foreach (var dir in dirs)
{
var dirInfo = new DirectoryInfo(dir);
if (dirInfo.Name == "bin" || dirInfo.Name == "obj" || dirInfo.Name == "debug" || dirInfo.Name == "tempPE" || dirInfo.Name == "java" || dirInfo.Name == "res") continue;
var files = Directory.GetFiles(dir, "app.config");
if (files.Length == 0)
{
ScanDir(dir);
continue;
}
Process(dir);
//ScanDir(dir);
}
}
private static void Process(string dir)
{
var fi = new FileInfo(Path.Combine(dir, AppConfigName));
if (fi.CreationTime.Date != DateTime.Now.Date) return;
if (AskConfirmation)
{
Console.WriteLine("Scan " + dir.Replace(RootFolder, ""));
Console.Write("Remove (y)es or (n)o ?");
var key = Console.ReadKey();
Console.WriteLine();
if (key.Key.ToString() =="Y")
// remove app.config
RemoveAppConfig(dir, fi);
}
else
RemoveAppConfig(dir, fi);
}
private static void RemoveAppConfig(string dir, FileInfo fi)
{
var csProjs = Directory.GetFiles(dir, "*.csproj");
foreach (var csProj in csProjs)
{
var txt = File.ReadAllText(csProj);
txt = Regex.Replace(txt,"<None Include=\"App.Config\" />", "",RegexOptions.IgnoreCase);
File.Delete(csProj);
File.WriteAllText(csProj, txt);
}
File.Delete(fi.FullName);
// todo: undo in tfs
Console.WriteLine("Deleted");
}
}

Eclipse RCP local history is empty

I'm trying to get the local history for a file, but its always empty:
FileSystemResourceManager fsm =
((org.eclipse.core.internal.resources.Workspace)ResourcesPlugin.getWorkspace()).getFileSystemManager();
IFileState[] fileStates =
fsm.getHistoryStore().getStates(myFile.getFullPath(),null);
In the .metadata/.plugins/org.eclipse.core.resources/.history/ folder I can find the items for the file, but I cant reach them via code.
The APIs you are using are internal use only and are not part of the Eclipse API, see Eclipse API Rules of Engagement.
You get the IFileState from an IFile object using the getHistory method.
IFile file = get ifile
IFileState [] states = file.getHistory(progress monitor);

Servlet cannot find the file I'm trying to open

I read that the servlets map the current location based on the url. Clicking a button from my Home.jsp page directs me to my servlet, ExcelUploader. The URL when said button is clicked is
http://localhost:8080/ServletExample/ExcelUploader
I'm trying to open an excel file located in the same folder as my JSP. so that means I have to move one folder up relative to the url above. I have this in my servlet:
InputStream inp = new FileInputStream("../OpenMe.xls");
However I'm still getting a
java.io.FileNotFoundException: ..\OpenMe.xls (The system cannot find the file specified)
This is how my project is setup:
The FileInputStream operates on the local disk file system relative to the working directory and knows absolutely nothing about the fact that it's invoked from a Java EE web application. Any relative path you pass to it is relative to the folder which was been opened at the moment the command to start the server is executed. This is often the server's own installation folder, but in case of an IDE this can also be project's own root folder. This variable is not controllable from inside your Java code. You should not be relying on that.
You've stored the file as a resource of the public webcontent. So it's available as a webcontent resource by ServletContext#getResourceAsStream() which returns an InputStream. If you have absolutely a legitimate reason to invoke the servlet by its URL instead of just using the file's own URL http://localhost:8080/ServletExample/OpenMe.xls, then you should be getting at as follows:
InputStream input = getServletContext().getResourceAsStream("/OpenMe.xls");
// ...
If your intent is indeed to restrict the file's access to by the servlet only, you might want to consider to move the file into the /WEB-INF folder, so that the enduser can never open it directly by entering the file's own URL. You only need to change the resource path accordingly.
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/OpenMe.xls");
// ...
You should not be using getRealPath() as suggested by the other answer. This won't work when the servletcontainer is configured to expand the WAR file into memory instead of into local disk file system, which is often the case in 3rd party hosts. It would return null then.
See also:
getResourceAsStream() vs FileInputStream
Paths for files that live in the webtree have to be "translated" using getRealPath before they are usable, like this:
File excelFile = new File(getServletContext().getRealPath("/OpenMe.xls"));
While you're at it, using the default package isn't a good idea, create a package for your files.