I recently tried packaging a Java app for distribution in the Mac App Store, but discovered that by bundling the default JRE, the app increased its file size by about 138 MB. I would like to reduce the size of the JRE by stripping out components that I don't need (e.g. Corba, JavaFX, XML parsing), thus resulting in a smaller increase when I bundle it into an app.
There are a couple of questions, like this one, that give some guidelines about what components to remove, but none that actually describe how to go about reducing it. What do I need to do to reduce the size of the JRE? Are there certain tools? Do I just download the source and hack out the classes I don't want? Do I edit my currently installed JRE? I'm not really sure where to begin.
I havent tested this myself but after some searching heres what I have found.
The Packaging a Java App for Distribution on a Mac guide gives you a basic look at how to bundle the app (which it sounds like you got already). From there I followed the docs for app bundler, on that page under "runtime" you see you can explicitly include or exclude files/folders from the bundling.
According to their docs
"By default, only the contents of the jre/ directory will be included with the bundled application. All executable content (i.e. bin/, jre/bin/) is excluded. Additional content can be included or excluded using nested <include> and <exclude> elements, respectively."
From that I took their sample code and added an exclude statement:
<-- Import environment variables -->
<property environment="env"/>
<-- Define the appbundler task -->
<taskdef name="bundleapp" classname="com.oracle.appbundler.AppBundlerTask"/>
<-- Create the app bundle -->
<target name="bundle-swingset" depends="package">
<bundleapp outputdirectory="."
name="Test"
displayname="Test"
identifier="com.oracle.javafx.swing.Test"
shortversion="1.0"
applicationCategory="public.app-category.developer-tools"
mainclassname="com/javafx/main/Main">
<runtime dir="${env.JAVA_HOME}">
<exclude name="Java IDL Server Tool" /> <!-- exclude from bundle -->
</runtime>
<classpath file="${user.home}/bin/javafx-samples-2.2.0/SwingInterop.jar"/>
<option value="-Dapple.laf.useScreenMenuBar=true"/>
</bundleapp>
</target>
A full list of optional excludes can be found in the JRE root - $JAVA_HOME/README.txt. Do a find for the text Optional Files and Directories and you'll be at the header of it. I am looking at the JRE7 installation on my computer, the JRE6 readme didnt seem to have anything in it.
I know this isn't working the example you're looking for but I hope it helps you figure it out.
Related
I'm trying to build soot.
I've downloaded the source code of JastAddExtensions using svn co https://svn.sable.mcgill.ca/abc/trunk/JastAddExtensions/, checked out the code of Soot using
git remote add soot https://github.com/Sable/soot.git
git pull soot develop.
Then I tried to build Soot using Ant and got following error message:
D:\dev\ro-01\soot\build.xml:102: The following error occurred while executing this line:
D:\dev\ro-01\JastAddExtensions\SootJastAddJ\build.xml:18: taskdef class JFlex.anttask.JFlexTask cannot be found
using the classloader AntClassLoader[]
How can I fix this error? Where can I download a version of code of JastAddExtensions\SootJastAddJ, which is compatible with current version of Soot?
You will get help faster on the Soot mailing list. You do not need do build the JastAdd part of Soot. It's pre-built in the directory "generated".
Check out:
http://jflex.de/jflex_anttask.html
Simple answer: You probably haven’t copied the JFlex jar to ant’s library folder/directory.
If that doesn’t straighten you out… More complex solution: Find the soot Ant file, probably in the project root directory as build.xml.
Then find a task definition named “jflex” that probably looks like this:
<taskdef classname="jflex.anttask.JFlexTask" name="jflex" />
Change it to something like this:
<taskdef
name="jflex"
classname="jflex.anttask.JFlexTask"
classpath="${compiler_tools_path}${jflex_jar_name}"
/>
Up near the beginning, with the other properties, create a new one with the location of a directory/folder you create and copy the latest JFlex jar to:
<property
name="compiler_tools_path"
value="/Library/CompilerTools/"
/>
This is an appropriate place to create a directory/folder to store this on a Mac. Windows and Unix, anywhere externally installed jars are stored.
<property
name="jflex_jar_name"
value="jflex-1.5.1.jar"
/>
An example of a recent JFlex jar build. Check out:
http://jflex.de/
I hope this was helpful.
Jeff
I took a look at build.xml in the soot repository. The problem is with the target jastadd. The JustAdd compiler uses Beaver as its parser generator, which also requires JFlex as it's scanner generator for handling .flex files.
Just follow my simple solution mentioned previously. Make sure you rename the jflex-1.5.1.jar file that you copy to Ant's lib directory to "JFlex.jar" It's all in the document I gave you that first link to.
I'm answering this problem so late because I only just came across a similar problem with getting ant files to work with JFlex in Eclipse projects.
Jeff
I'm working on a PhoneGap/Cordova plugin that's supposed to provide a socket for sending and receiving OSC messages (Open Sound Control). For that purpose I'd like to use JavaOSC but I'm uncertain about how to include the library into my project.
I'm using Android Studio and I've basically followed this tutorial to set up my project. First I placed the raw JavaOSC class-files in the same directory as my OSCPlugin.class and placed the import declarations at the to of my OSCPlugin.class:
import com.illposed.osc;
That didn't work.
As a next step I tried to add the library from maven within the project's module settings. I was able to download the jar files from maven and install put them into /platforms/android/libs. Within the settings for the module 'android' I can see that 'Android API 17' is supposed to be used as SDK, including cordova-3.1.0 and com.illposed.osc:javaosc-core:0.2 - both activated. I can see the cordova-3.1.0.jar as well as javaosc-core-0.2.jar, containing com.illposed.osc in the navigator within Android Studio.
However, when trying to compile my project I get:
Gradle: cannot find symbol class osc
triggered from within OSCPlugin.class that contains the above mentioned import declaration
I have very little experience with Java and even less with Android development. But I'd be interested in solving this riddle and get started. I have searched the Java docs but the problem doesn't merely lie within Java but rather within the structure of the Android project.
I'd be thankful if someone could shed some light on this issue. Any hint's highly appreciated!
For one of my Phonegap projects I needed the Apache Commons Net, trying to follow these steps:
...
<source-file src="src/android/xxx.jar" target-dir="libs" framework="true" />
<source-file src="src/android/MyPlugin.java" target-dir="src/com/mypackage" />
...
unfortunately, without success. The trick was to embed the third-party library in another plugin (following the very plugin structure). Having the org.apache.commons.net as a top level directory:
org.apache.commons.net
+src
+android(this is where the .jar is located)
+www (empty, not referencing any .js)
+plugin.xml
For brevity, plugin.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
id="org.apache.commons.net"
version="0.1.0">
<name>org.apache.commons.net</name>
<description>org.apache.commons.net</description>
<license>Apache License, Version 2.0</license>
<keywords>org.apache.commons.net</keywords>
<!-- android -->
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="org.apache.commons.net">
<param name="android-package" value="org.apache.commons.net"/>
</feature>
</config-file>
<source-file src="src/android/commons-net-2.2.jar" target-dir="libs" framework="true" />
</platform>
</plugin>
Assuming the org.apache.commons.net directory is located in your local git repo, adding it to your project is as trivial as:
phonegap local plugin add /path/to/your/org.apache.commons.net
To add external library, basically all you have to do is copy the jar to the /libs folder.
Here you have a bad import in your source.
import is used to import a class by specifying the package name followed by the class name and here you only specify the class name, so the error "cannot find symbol class osc" you are having is because there is no class osc.
You should use either
import com.illposed.osc.*; if you want to import all classes from the package
or add an import for each class from the package that you are going to use.
And if you want make the plugin installable using the CLI or phonegap build, you also have to update plugin.xml to add the copy of the jar file.
ps in case you don't know, you won't be able to use classes from com.illposed.osc.ui as they are using swing and designed for the jvm and not android.
We got a GWT project in Eclipse, that otherwise works.
Now I want to have a script that runs on the server, which pulls the latest version from source control and compiles it on the server and deploys it.
This will save us a lot of manual work and allow us to deploy new version when on a connection with limited bandwidth (since we won't have to upload the application to the server).
After pulling the latest version of the source code, the script tries to compile the code using the following command:
java -cp "/path/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.0.v201211121240-rel-r42/gwt-2.5.0/*:/path/company/projects/pull-compile-deploy/X/X/src:/path/company/projects/pull-compile-deploy/X/X/war/WEB-INF/lib/*" com.google.gwt.dev.Compiler nl.company.projects.X
Compiling module nl.company.projects.X
Finding entry point classes
[ERROR] Unable to find type 'nl.company.projects.X.client.XMain'
[ERROR] Hint: Previous compiler errors may have made this type unavailable
[ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
All source code is in /path/company/projects/pull-compile-deploy/X/X/src and all used .jars (except for the GWT stuff) are in /path/company/projects/pull-compile-deploy/X/X/war/WEB-INF/lib/. Obviously something goes wrong.
Questions: The file /path/company/projects/pull-compile-deploy/X/X/src/nl/company/projects/X/client/XMain.java does exist and should imho be in the classpath?!
Anyone Any idea what might go wrong here?
Is it maybe possible to see in some log exactly the commands that eclipse executes for compilation? I looked at the build.xml that eclipse can export, but it seems that does not contain a target to compile for production.
something else: apperantly GWT expects the X.gwt.xml to be at /path/company/projects/pull-compile-deploy/X/X/src/nl/company/project/X.gwt.xml, whereas eclipse put it in /path/company/projects/pull-compile-deploy/X/X/src/nl/company/project/X/X.gwt.xml (i.e. nested one directory deeper), I fixed this by creating a symbolic link.
Further Edit:
Since one answer focused on how I invoked the compilation tools, I have rewritten that in Ant, see below.
The problem remains of course.
<!-- Compile the source using javac. -->
<target name="compile" depends="init">
<javac srcdir="src/" destdir="bin/">
<classpath refid="project.classpath"/>
</javac>
</target>
<!-- Use the GWT-compiler. -->
<target name="gwt-compile" depends="compile">
<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
<classpath>
<path refid="project.classpath"/>
<pathelement location="src/"/>
<pathelement location="bin/"/>
</classpath>
<jvmarg value="-Xmx512M"/>
<arg value="${module.name}"/>
</java>
</target>
Anything wrong with the above Ant-script?
module.name = nl.company.projects.X and the path with refid="project.classpath" contains all used libraries aswell as the GWT libraries (gwt-user.jar, gwt-dev.jar and validation-api-1.0.0.GA(-source).jar).
The XMain class inherits nothing (other than from Object) and only implements EntryPoint (which is included in the gwt-user.jar). So I do not think the problem is related to the second hint that the compiler gives.
Any ideas?
GWT requires you to javac your classes, it needs both the *.java and the *.class files.
This has not always been the case, and should change back in the future (see https://code.google.com/p/google-web-toolkit/issues/detail?id=7602 for instance), but for now that's the state of affair: you need to javac before you can com.google.gwt.dev.Compiler.
javac -cp "/path/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.0.v201211121240-rel-r42/gwt-2.5.0/*:/path/company/projects/pull-compile-deploy/X/X/war/WEB-INF/lib/*" -sourcepath /path/company/projects/pull-compile-deploy/X/X/src /path/company/projects/pull-compile-deploy/X/X/src/nl/company/projects/X.java -d /path/company/projects/pull-compile-deploy/X/X/bin
java -cp "/path/eclipse/plugins/com.google.gwt.eclipse.sdkbundle_2.5.0.v201211121240-rel-r42/gwt-2.5.0/*:/path/company/projects/pull-compile-deploy/X/X/src:/path/company/projects/pull-compile-deploy/X/X/bin:/path/company/projects/pull-compile-deploy/X/X/war/WEB-INF/lib/*" com.google.gwt.dev.Compiler nl.company.projects.X
(please double-check the above commands before use)
EDIT: (in response to your "question" re. the X.gwt.xml): GWT expects the X.gwt.xml at nl/company/projects/X.gwt.xml because that's what you told it to use: module.name = nl.company.projects.x. If the file is at nl/company/projects/X/X.gt.xml then use nl.company.projects.X.X as the module name. Using a symbolic link here is likely to be the problem: the source path for the module (search for <source at https://developers.google.com/web-toolkit/doc/latest/DevGuideOrganizingProjects#DevGuideModuleXml) will then be nl/company/projects/client and thus won't include nl/company/projects/X/client where your XMain class lives; it's this unavailable to the GWT compiler.
That said, I totally agree with SSR: use a decent build tool: Ant, Maven, Gradle, Make, whatever, it'll make your life so much easier. A build tool that manages dependencies (Ant+Ivy, Maven, Gradle) is even better IMO.
Why would you put yourself through such non-standard build exercise like this.
If it is non-academic project then USE maven. If you find maven difficult then use ant.
Examples for both type are provided by GWT team - http://code.google.com/p/google-web-toolkit/source/browse/#svn%2Ftrunk%2Fsamples.
Note - maven has plugins to do most of the stuff you are trying in standardized way.
I'm having trouble getting javadoc to reference another project's API.
There's a strict hirearchy between the projects (a "common" project referenced by an "app" project).
Both projects build just fine, so there's no issue with classes and packages not actually existing.
My understanding is that javadoc doesn't have a sort of buildpath in the same way that Java does, but uses links to other javadoc websites instead. There's some pretty logical reasons for this in terms of being able to generate HTML cross references.
My attempt to make this goes as follows:
I've built the javadoc for the common project
I threw that on a webserver on my intranet
I added a link to the api (on my intranet) to the javadoc ant task in the app project.
I attempted to build the app project
Javadoc still spits out error messages of the form:
[javadoc] C:\Users\couling\workspace\app\src\com\blahblah\app\AppMain.java:14: package com.blahblah.common.foo does not exist
[javadoc] import com.blahblah.common.foo.Bar
[javadoc] ^
The resulting javadoc has no cross links between the projects.
The ant tasks for the two projects are as follows:
Common:
<javadoc
access="protected"
author="true"
classpath="."
destdir="out/doc/docs"
nodeprecated="false"
nodeprecatedlist="false"
noindex="false"
nonavbar="false"
notree="false"
packagenames="*"
source="1.6"
sourcepath="src"
splitindex="true"
use="true"
version="true">
<link href="http://download.oracle.com/javase/6/docs/api/" />
</javadoc>
App:
<javadoc
access="protected"
author="true"
classpath="."
destdir="out/doc/docs"
nodeprecated="false"
nodeprecatedlist="false"
noindex="false"
nonavbar="false"
notree="false"
packagenames="com.blahblah.app.*"
source="1.6"
sourcepath="src"
splitindex="true"
use="true"
version="true">
<link href="http://intranet.blahblah.com/api/common/docs/" />
<link href="http://download.oracle.com/javase/6/docs/api/" />
</javadoc>
Any thoughts on what I need to do to get app to reference common?
The <link> element (or the -link option for command line javadoc) only help with generating the links - but Javadoc stops at an earlier point, it can't really work with your app classes if they reference unknown (common) classes.
In this respect, Javadoc works just like Javac - you must somehow point it to the classes to be used, i.e. they must be in the class path. You can use a <classpath> element to point to the jar file or class directory, or a <sourcepath> element, to point to the sources (do this if you need to inherit some comments from them).
This is not needed for linking to the standard API, since it is already included in the compiler.
Note that linking in this way requires Javadoc to download the package-list from this URL - you can instead point to a local directory which contains this package-list file.
I am building my application .cod file without using Blackberry JDE or Eclipse plugin. Everything works fine in the simulator if I hardcode the String arguments which my main() method needs. (I am using Maven to build.)
How do you specify main method arguments? In the Eclipse BlackBerry project properties, in the Application tab, you can specify these arguments. So I assume there must be an equivalent way of doing this by hand-editing the .jdp file or specifying an argument to rapc compiler?
you can use bb-ant-tools
and you can give alternate entry point like this
<rapc destdir="${dist}" jdehome="${jdehome}" jdkhome="${javahome}" output="${output}">
<jdp type="cldc"
title="${title}" vendor="${vendor}"
version="${version}"
description="${description}"
systemmodule="true"
runonstartup="true"
startuptier="7">
<entry title="${title}"
arguments="click"
systemmodule="false"
runonstartup="false"
startuptier="7"
ribbonposition="0"
icon="../img/icon.png" />
</jdp>
<src>
<fileset dir="${src}">
<include name="**/*.java" />
<include name="resources/**/*.*" />
</fileset>
</src>
</rapc>
I found that I had to modify two files.
I modified the .jdp file, adding the line:
MidletClass=arg1&arg2
And I modified the .rapc file, modifying the line:
MIDlet-1: AppTitle,main/resources/icon.png,arg1&arg2
It appears that at least an ampersand & or pipe | character can be used as an argument delimiter. A whitespace character will not work as a delimiter.
Now I can build with Maven. I learned all of this by using the officially-blessed RIM Eclipse plugin, setting the main arguments through the Blackberry project dialog box, and then seeing how those underlying files were changed by the plugin.