android load class from jar file - java

I have written a Java Classloader to load classes from a .jar file.
However when I load a Class I get a ClassNotFoundException. The .jar file is located in folder assets. Before the operation I copied the .jar file in another directory.
Why does it happen and how can I load class from jar file?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
try {
final File dexInternalStoragePath = new File(getDir("lib", Context.MODE_PRIVATE), SECONDARY_DEX_NAME);
(new PrepareDexTask()).execute(dexInternalStoragePath);
if (dexInternalStoragePath.exists()) {
final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);
DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(), null, getClassLoader());
try {
JarFile jarFile = new JarFile(dexInternalStoragePath.getAbsolutePath());
Enumeration<?> e = jarFile.entries();
URL[] urls = { new URL("jar:file:" + dexInternalStoragePath.getAbsolutePath() + "!/") };
URLClassLoader cl1 = URLClassLoader.newInstance(urls);
while (e.hasMoreElements()) {
JarEntry je = (JarEntry) e.nextElement();
if (je.isDirectory() || !je.getName().endsWith(".class")) {
continue;
}
String className = je.getName().substring(0, je.getName().length() - 6);
className = className.replace('/', '.');
if (className.equals("com.common.lvl.LibraryProvider")) {
LibraryInterface lib = (LibraryInterface) Class.forName(className, true, cl1).newInstance();
//Class<?> libProviderClazz = cl1.loadClass(className);
//LibraryInterface lib = (LibraryInterface) libProviderClazz.newInstance();
lib.CheckLVL(this, "hello");
}
}
// Class<?> libProviderClazz =
// cl.loadClass("com.common.lvl.LibraryProvider");
// LibraryInterface lib = (LibraryInterface)
// libProviderClazz.newInstance();
// lib.CheckLVL(this, "hello");
} catch (Exception ex) {
Logger.Instance().WriteLine(this, ex.getMessage());
}
}
} catch (Exception ex) {
}
}
private boolean prepareDex(File dexInternalStoragePath) {
BufferedInputStream bis = null;
OutputStream dexWriter = null;
try {
bis = new BufferedInputStream(getAssets().open(SECONDARY_DEX_NAME));
dexWriter = new BufferedOutputStream(new FileOutputStream(dexInternalStoragePath));
byte[] buf = new byte[BUF_SIZE];
int len;
while ((len = bis.read(buf, 0, BUF_SIZE)) > 0) {
dexWriter.write(buf, 0, len);
}
dexWriter.close();
bis.close();
return true;
} catch (IOException e) {
if (dexWriter != null) {
try {
dexWriter.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return false;
}
}
private class PrepareDexTask extends AsyncTask<File, Void, Boolean> {
#Override
protected void onCancelled() {
super.onCancelled();
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
}
#Override
protected Boolean doInBackground(File... dexInternalStoragePaths) {
prepareDex(dexInternalStoragePaths[0]);
return null;
}
}

Add your jar file, like below
go to -> project properties in eclipse -> java build path -> Libraries -> Add External Jar, And browse and locate you jar file.

Related

How to restore file from GDrive?

I am making an app which stores its SQLite Database backup on GDrive. I succeeded in signing in and uploading the file in the drive but failed to restore it. Following is the code.
I use SQLiteDatabase to store the fileID so that when it is required while updating and restoring, it can be used. I am looking for a method which will make use of FileID to restore.
Error occurs at file.getDownloadUrl() and file.getContent().
class DriveClassHelper
{
private final Executor mExecutor = Executors.newSingleThreadExecutor();
private static Drive mDriveService;
private String FileID = null;
private static String filePath = "/data/data/com.example.gdrivebackup/databases/Data.db";
DriveClassHelper(Drive mDriveService)
{
DriveClassHelper.mDriveService = mDriveService;
}
// ---------------------------------- TO BackUp on Drive -------------------------------------------
public Task<String> createFile()
{
return Tasks.call(mExecutor, () ->
{
File fileMetaData = new File();
fileMetaData.setName("Backup");
java.io.File file = new java.io.File(filePath);
String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("application/x-sqlite-3");
FileContent mediaContent = new FileContent(mimeType, file);
File myFile = null;
FileID = getFileIDFromDatabase();
try {
if (FileID != null) {
Log.i("CALLED : ", FileID);
//mDriveService.files().delete().execute();
myFile = mDriveService.files().update(FileID, fileMetaData, mediaContent).execute();
} else {
myFile = mDriveService.files().create(fileMetaData, mediaContent).execute();
MainActivity.demoSQLite.insertData(myFile.getId());
}
} catch (Exception e) {
e.printStackTrace();
}
if (myFile == null) {
throw new IOException("Null Result when requesting file creation");
}
Log.i("ID:", myFile.getId());
return myFile.getId();
}
);
}
// -------------------------------------------------------------------------------------------------
// ---------------------------------- TO get File ID -------------------------------------------
private static String getFileIDFromDatabase()
{
String FileIDFromMethod = null;
Cursor result = MainActivity.demoSQLite.getData();
if (result.getCount() == 0) {
Log.i("CURSOR :", "NO ENTRY");
return null;
} else {
while (result.moveToNext()) {
FileIDFromMethod = result.getString(0);
}
return FileIDFromMethod;
}
}
// -------------------------------------------------------------------------------------------------
// ---------------------------------- TO Restore -------------------------------------------
public static class Restore extends AsyncTask<Void, Void, String>
{
#Override
protected String doInBackground(Void... params) {
String fileId = null;
try
{
fileId = getFileIDFromDatabase();
if (fileId != null)
{
File file = mDriveService.files().get(fileId).execute();
downloadFile(file);
}
else
{
return null;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return fileId;
}
private void downloadFile(File file)
{
InputStream mInput = null;
FileOutputStream mOutput = null;
if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) //Error occurs at file.getDownloadUrl()
{
try
{
HttpResponse resp = mDriveService.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();
mInput = resp.getContent();
String outFileName = "file://" + Environment.getDataDirectory().getPath() + filePath;
// Log.e("com.example.myapp", "getDatabasePath="+ getDatabasePath(""));
//Log.e("com.example.myapp", "outFileName="+outFileName);
// String outFileName = "../databases/" + "Quickpay.db";
mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0)
{
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
}
catch (IOException e)
{
// An error occurred.
e.printStackTrace();
// return null;
}
finally
{
try
{
//Close the streams
if (mOutput != null)
{
mOutput.close();
}
if (mInput != null)
{
mInput.close();
}
}
catch (IOException e)
{
Log.e("com.example.myapp", "failed to close databases");
}
}
}
else
{
// The file doesn't have any content stored on Drive.
// return null;
Log.e("com.example.myapp", "No content on Drive");
}
}
}
}
The Gradle file is like
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0')
{
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.api-client:google-api-client-android:1.26.0')
{
exclude group: 'org.apache.httpcomponents'
}
implementation 'com.google.http-client:google-http-client-gson:1.26.0'
As far as i know Download URL is only avalibale in Google drive api v2 and not in V3.
Short lived download URL for the file. This field is only populated for files with content stored in Google Drive; it is not populated for Google Docs or shortcut files.
It was not very stable in my opinion as not all file types would return a download url.
Using Google Drive v3 you should download the file using a stream.
String fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().get(fileId)
.executeMediaAndDownloadTo(outputStream);
This should work with the restore. Let me know if it doesnt and i will have a look its been a while since i have tried restore.

Thrown IllegalArgumentException when using java.nio

Trying to download file by url. For that using java.nio library. The code above work perfect for sdk 24 and above but getting IllegalArgumentException for android sdk 23 and below. I'm getting the error when trying transfer the data. Dear Friends can you please clarify which is the problem.
private void downloadFile(final String itemUrl) {
new Thread(new Runnable() {
#Override
public void run() {
ReadableByteChannel readableByteChannel = null;
FileOutputStream fOutStream = null;
String root =
getApplicationContext().getApplicationInfo().dataDir;
File myDir = new File(root + "/downloadedSongs");
if (!myDir.exists()) {
myDir.mkdirs();
}
File file = new File(myDir, itemTitle);
if (file.exists()) {
file.delete();
}
try {
URL url = new URL(itemUrl);
readableByteChannel =
Channels.newChannel(url.openStream());
fOutStream = new FileOutputStream(file);
fOutStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (IOException e) {
orderAction = Enums.OrderAction.Delete;
} catch (IllegalArgumentException e) {
orderAction = Enums.OrderAction.Delete;
Crashlytics.logException(e);
} finally {
try {
if (fOutStream != null) {
fOutStream.close();
}
if (readableByteChannel != null) {
readableByteChannel.close();
}
} catch (IOException ioExObj) {
orderAction = Enums.OrderAction.Delete;
}
closeNotification(orderAction);
}
}
}).start();
}
Fatal Exception: java.lang.IllegalArgumentException: position=0 count=9223372036854775807 at java.nio.FileChannelImpl.transferFrom(FileChannelImpl.java:370) at am.itsoft.youtomp3.services.DnlService$1.run(DnlService.java:169) at java.lang.Thread.run(Thread.java:818)
The reason is in this argument: Long.MAX_VALUE
Right code:
FileChannel destChannel = fOutStream.getChannel();
long blockSize;
if (Build.VERSION.SDK_INT > 23) {
long blockSize = Long.MAX_VALUE;
} else {
long blockSize = 8*1024;
}
long position = 0;
long loaded;
while ((loaded = destChannel.transferFrom(readableByteChannel, position, blockSize)) > 0) {
position += loaded;
}

Can't write text into .properties file with FileOutputStream on android

This is a part of the code I have in my SettingsActivity.java file:
public class SettingsActivity extends Activity {
Thread refresh = new Thread() {
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Config.writeFile();
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
if (new File(MainActivity.ConfigPath).exists()) {
Config.loadFile();
} else {
Config.writeFile();
}
refresh.start();
}
}
And this is in my Config.java file:
public class Config {
public static void writeFile() {
try {
Properties properties = new Properties();
properties.setProperty("StartOnBoot", String.valueOf(MainActivity.StartOnBoot));
//StartOnBoot is a boolean in the MainActivity.java file
File file = new File("config/app.properties");
file.setWritable(true);
FileOutputStream fileOut = new FileOutputStream(file);
properties.store(fileOut, "Favorite Things");
fileOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void loadFile() {
try {
Properties properties = new Properties();
FileInputStream fileIn = new FileInputStream(new File("config/app.properties"));
properties.load(fileIn);
MainActivity.StartOnBoot = Boolean.valueOf(properties.getProperty("StartOnBoot"));
fileIn.close();
System.out.println(properties.getProperty("StartOnBoot"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is what my Project explorer window looks like
This is what is shown in a logfile from logcat:
07-09 16:16:32.416: W/System.err(621): at
java.io.FileOutputStream.(FileOutputStream.java:94)
And the .properties file still remains empty.
Any ideas how to make it work?
PS:
-API 10
-Target SDK Version 22
-I didn't add any permissions to the AndroidManifest.xml file
For handling properties in Android, use this class:
public class MyPropertiesHolder {
public static int MODE_CREATE = 0;
public static int MODE_UPDATE = 1;
private Context context;
private String filename;
private Properties properties;
public MyPropertiesHolder(Context context, String filename, int mode) throws IOException {
this.context = context;
this.filename = filename;
this.properties = new Properties();
if(mode != MODE_CREATE) {
FileInputStream inputStream = context.openFileInput(filename);
properties.load(inputStream);
inputStream.close();
}
}
public String getProperty(String key){
return (String) properties.get(key);
}
public void setProperty(String key, String value) {
properties.setProperty(key, value);
}
public void commit() throws IOException {
FileOutputStream outputStream = context.openFileOutput(filename, Context.MODE_PRIVATE);
properties.store(outputStream, "");
outputStream.close();
}
}
This is how you use the above class (assuming you are in an Activity):
Creating a new properties file:
MyPropertiesHolder propHolder = new MyPropertiesHolder(this, "test.properties", MyPropertiesHolder.MODE_CREATE);
propHolder.setProperty("test1", "test1");
propHolder.setProperty("test2", "test2");
propHolder.commit();
Updating existing properties file:
MyPropertiesHolder propHolder2 = new MyPropertiesHolder(this, "test.properties", MyPropertiesHolder.MODE_UPDATE);
String test1 = propHolder2.getProperty("test1");
String test2 = propHolder2.getProperty("test2");
propHolder2.setProperty("test3", "test3");
propHolder2.setProperty("test4", "test4");
propHolder2.commit();
Note: You won't see this file in assets directory.

How open a .scala file inside a Jar

I have a .scala file inside a JAR, how do i open from my code that isn't part of the jar?
For some additional precisions the jar file does not on classpath.
Here an example of my code. It works partially, the file on the jar is open but for that i create it from the folder "lib'.
Have you another idea for evitate the creation of the file on the folder?
Thanks !
protected Object openDialogBox(Control cellEditorWindow, Object value, String jarFileName)
throws CoreException, IOException {
IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IProject myProject = myWorkspaceRoot.getProject(ActiveProject.getNameProject());
String fileProgramName = (String) value;
InputStream stream;
final boolean readOnly = (jarFileName != null);
if (myProject.exists() && myProject.isOpen()) {
IFolder sourceFolder = myProject.getFolder( (jarFileName != null) ? "lib" : "src" );
if (sourceFolder.exists()) {
final IFile programFile = sourceFolder.getFile(fileProgramName);
if ( jarFileName != null ) {
programFile.delete(true, new NullProgressMonitor());
stream = JarUtil.getProgramFromJar(jarFileName, fileProgramName);
}
else {
stream = createContentStream(myProject.getName(), programFile.getName().replace(".scala", ""));
}
if (!programFile.exists()) {
// create the file
programFile.create(stream, true, new NullProgressMonitor());
}
programFile.refreshLocal(IResource.DEPTH_ZERO, null);
stream.close();
cellEditorWindow.getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
IWorkbenchPage page = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage();
try {
ResourceAttributes myAttributes = programFile.getResourceAttributes();
if (myAttributes == null) {
myAttributes = new ResourceAttributes();
}
myAttributes.setReadOnly(readOnly);
try {
programFile.setResourceAttributes(myAttributes);
} catch (CoreException e) {
e.printStackTrace();
}
IDE.openEditor(page, programFile, true);
} catch (PartInitException e) {
}
}
});
return value;
}
return null;
}
return null;
}

Extracting files in .iso using jSevenZip

I'm trying to extract the files in an .iso file I have. There are no errors and the console prints out all the files inside. However, none of the files get extracted. Any help is greatly appreciated!
I was able to find this link but I can't seem to integrate it in to my project.
Link to code example
class DownloadWorker extends SwingWorker<String, Object> {
private String flocation;
private JLabel out;
public DownloadWorker(String location, JLabel fout)
{
this.flocation = location;
this.out = fout;
}
#Override
public String doInBackground() {
//download here
out.setText("Beginning download. This may take a few minutes.");
try {
//ProgressBar/Install
System.out.println("FILELOCATION:\n----------");
System.out.println(flocation);
String URL_LOCATION = "http://www.futureretrogaming.tk/gamefiles/ProfessorPhys.iso";
String LOCAL_FILE = (flocation + "\\ProfessorPhys\\");
File localfile = new File(LOCAL_FILE);
if (localfile.exists()) {
System.out.println("Directory exists!");
}
else {
System.out.println("Directory doesn't exist! Creating...");
localfile.mkdir();
if (localfile.exists())
System.out.println("Directory created!");
}
System.out.println("LOCALFILE:\n-------");
System.out.println(LOCAL_FILE);
URL website = new URL(URL_LOCATION);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(LOCAL_FILE+"\\ProfessorPhys.iso\\");
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
System.out.println("--------\nDone Downloading\n---------");
RandomAccessFile randomAccessFile = null;
ISevenZipInArchive inArchive = null;
try {
randomAccessFile = new RandomAccessFile(localfile +"\\ProfessorPhys.iso\\", "r");
inArchive = SevenZip.openInArchive(null, // autodetect archive type
new RandomAccessFileInStream(randomAccessFile));
// Getting simple interface of the archive inArchive
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
System.out.println(" Hash | Size | Filename");
System.out.println("----------+------------+---------");
for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
final int[] hash = new int[] { 0 };
if (!item.isFolder()) {
ExtractOperationResult result;
final long[] sizeArray = new long[1];
result = item.extractSlow(new ISequentialOutStream() {
public int write(byte[] data) throws SevenZipException {
hash[0] ^= Arrays.hashCode(data); // Consume data
sizeArray[0] += data.length;
return data.length; // Return amount of consumed data
}
});
if (result == ExtractOperationResult.OK) {
System.out.println(String.format("%9X | %10s | %s", //
hash[0], sizeArray[0], item.getPath()));
} else {
System.err.println("Error extracting item: " + result);
}
}
}
} catch (Exception e) {
System.err.println("Error occurs: " + e);
System.exit(1);
} finally {
if (inArchive != null) {
try {
inArchive.close();
} catch (SevenZipException e) {
System.err.println("Error closing archive: " + e);
}
}
if (randomAccessFile != null) {
try {
randomAccessFile.close();
} catch (IOException e) {
System.err.println("Error closing file: " + e);
}
}
}
} catch (Exception e) {
System.out.println(e);
}
return "done";
}
#Override
protected void done() {
//done
out.setText(out.getText() + "\n Operation Done");
}
}
Code I'm trying to implement:
public class ExtractorUtil {
private static Logger logger = Logger.getLogger(ExtractorUtil.class.getCanonicalName());
public static void extract(File file, String extractPath) throws Exception {
ISevenZipInArchive inArchive = null;
RandomAccessFile randomAccessFile = null;
randomAccessFile = new RandomAccessFile(file, "r");
inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
inArchive.extract(null, false, new MyExtractCallback(inArchive, extractPath));
if (inArchive != null) {
inArchive.close();
}
if (randomAccessFile != null) {
randomAccessFile.close();
}
}
public static class MyExtractCallback implements IArchiveExtractCallback {
private final ISevenZipInArchive inArchive;
private final String extractPath;
public MyExtractCallback(ISevenZipInArchive inArchive, String extractPath) {
this.inArchive = inArchive;
this.extractPath = extractPath;
}
#Override
public ISequentialOutStream getStream(final int index, ExtractAskMode extractAskMode) throws SevenZipException {
return new ISequentialOutStream() {
#Override
public int write(byte[] data) throws SevenZipException {
String filePath = inArchive.getStringProperty(index, PropID.PATH);
FileOutputStream fos = null;
try {
File dir = new File(extractPath);
File path = new File(extractPath + filePath);
if (!dir.exists()) {
dir.mkdirs();
}
if (!path.exists()) {
path.createNewFile();
}
fos = new FileOutputStream(path, true);
fos.write(data);
} catch (IOException e) {
logger.severe(e.getLocalizedMessage());
} finally {
try {
if (fos != null) {
fos.flush();
fos.close();
}
} catch (IOException e) {
logger.severe(e.getLocalizedMessage());
}
}
return data.length;
}
};
}

Categories

Resources