Closed GitMensch closed 6 years ago
Oops, I have never put my fingers in the Apple stuff. Can you make sure it's not the blank in the pathname that causes the trouble?
Can you make sure it's not the blank in the pathname that causes the trouble?
Rechecked with c:\dev\Structorizer
- still the same.
Note: also happens when running makeJar
... and when running makeStructorizer
in a clean checkout:
$ ./makeStructorizer
Removing .class files
Changing into src directory
/c/dev/Structorizer/src /c/dev/Structorizer
Compiling non-dependant classes
lu\fisch\structorizer\generators\BASHGenerator.java:122: error: package lu.fisch.structorizer.elements does not exist
import lu.fisch.structorizer.elements.Alternative;
^
What did I miss?!?
My script for creating the source package uploaded to my site contains these lines in order to clean if from the Apple specific code:
echo "Removing MAC specific files"
rm source/src/Structorizer.java
rm source/src/Structorizer.clean
rm source/lib/AppleJavaExtensions.jar
echo "Copy clean launcher class"
cp -f src/Structorizer.clean source/src/Structorizer.java
@fesch Thank you for the note. I could rearrange the currents scripts and do a PR. Please tell me what you think of the following:
new script "prepareDist" (with optional parameters "mac" / "jar" or "bigjar")
removes "dist" directory if existing
copy the src, lib and scripts/manifests to "dist" directory
when the optional parameter "mac" is not given: do what your script does
when the optional parameter "jar" / "bigjar" is given execute "makeStructorizer" there + makeJar / makeBigJar
(not needed but still suggested): moving the existing build scripts and manifests to a "scripts" folder Question: What is the purpose of startStructorizerAgain script?
Yes, I think this will be a fine solution for everyone who want's to make his own release.
I have no idea what startStructorizerAgain was written for. My name is inside, yes, but I can't even remind having written it. :-(
@fesch Can I remove startStructorizerAgain? Do you have other scripts that may be added into this process (ideally you can do everything you need from a clean checkout)?
I have no problem if it is being removed. The only one I personnaly need for the release, is the "sign" script, but that one is not on GitHub as it contains sensible data ;)
I have never needed nor used startStructorizerAgain, either, if you must know. So I guess I will hardly miss it in future. ;-)
The repo contains a couple of scripts now whose sole purpose it is to prepare and build from source. Any chance migrating this to a Makefile? This would greatly reduce redundancies as well. Not quite sure how Makefile support on Mac is, but generally speaking it's the de-facto standard in the Linux/Unix world.
I'm facing similar issues while compiling on Linux. I assume the fix above will clear that up. since Mac specific code is the issue for me as well.
Structorizer.java:329: error: package com.apple.eawt does not exist
com.apple.eawt.Application application = com.apple.eawt.Application.getApplication();
^
Structorizer.java:329: error: package com.apple.eawt does not exist
com.apple.eawt.Application application = com.apple.eawt.Application.getApplication();
^
Structorizer.java:334: error: package com.apple.eawt does not exist
application.addApplicationListener(new com.apple.eawt.ApplicationAdapter() {
^
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
3 errors
As said before, the file Structorizer.java should be replaced by the file Structorizer.clean if you want to build Structorizer without the Apple extensions. Unfortunately I did not find a better way to do this, as in Java we have no real equivalent for C's #ifdef compiler directive.
I'll open a new issue for the Makeflile request.
@fesch Can I suggest to swap the files? Obviously they lead to confusion and something like Structorizer.java -> Structorizer.apple.java Structorizer.clean -> Structorizer.java
Would solve the issue.
Yes, I could do that, too. Or I find a way to enable Apple support by cmd and disable it afterwards. Maybe with a little sed command will do the trick. I have some ideas and will test them later on ...
I have completely removed all files except for Structorizer.java.
When calling makeStructorizer
, the Apple specific lines will be disabled automatically.
Maybe I should also add a big comment at the top of the file referring to the specific line if someone would like to comment out this part of the code by himself?
... of maybe I could use reflection to make the desired calls?
@fesch
When calling
makeStructorizer
, the Apple specific lines will be disabled automatically.
I wonder how you create the Apple variant of the product - obviously not with the script makeStructorizer
since it doesn't expect a parameter suppressing the code modification? And how is Structorizer.java restored after makeStructorizer
? Just by reverting the code?
The next thing I don't get is: In line 58 (of "makeStructorizer") you refer to Structorizer.Applet.java though you have removed that file...
The code in the repository will the Apple specific code always enabled.
I don't use the makeStructorizer
script neither for compiling nor for packaging. I don't use it at all!
I compile using NetBeans immediately. Then I launch another script, which is obviously not in the repository as it contains sensible data, to generate all the packages and documentation and upload it to the various servers.
Just realizing that I removed a file I should not have .... tzz
@fesch I don't use this script either, instead I let Eclipse do the job, and having the Apple extensions in the project, there is no complaint, you know. Of course, they are sort of dead weight in the jar whilst you don't work on a Mac ;-)
So perhaps your proposal to use reflection may really be the simplest way to handle this. We already use reflection for other purposes (like locales) in the code, hence it wouldn't be a new breach...
Go Reflection Go
The major difficulty is to find some equivalent to this subclass definition on the fly with reflection:
application.addApplicationListener(new com.apple.eawt.ApplicationAdapter() {
public void handleAbout(com.apple.eawt.ApplicationEvent e) {
mainform.diagram.aboutNSD();
e.setHandled(true);
}
// ...
});
I tried with something like:
if (System.getProperty("os.name").toLowerCase().startsWith("mac os x"))
{
try
{
// Test for availability of the named class (will throw an exception otherwise)
Class.forName("com.apple.eawt.Application");
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("apple.awt.graphics.UseQuartz", "true");
// FIXME The system does not necessarily provide a Java compiler
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
URL url = Structorizer.class.getClassLoader().getResource("StructorizerApplicationAdapter.java.txt");
compiler.run(null, null, null, url.getPath());
// Test whether the compilation has worked
Class<?> adapterClass = Class.forName("StructorizerApplicationAdapter");
Class<?> applClass = Class.forName("com.apple.eawt.Application");
Object application = applClass.newInstance();
//application.setEnabledPreferencesMenu(true);
Method method = applClass.getMethod("setEnabledPreferencesMenu", new Class[]{boolean.class});
method.invoke(application, new Object[]{true});
//application.addApplicationListener(new com.apple.eawt.ApplicationAdapter() { ...
Object adapter = adapterClass.newInstance();
//adapter.setMainform(mainform);
method = adapterClass.getMethod("setMainform", new Class[]{Mainform.class});
method.invoke(adapter, new Object[]{mainform});
method = applClass.getMethod("addApplicationListener", new Class[]{Class.forName("com.apple.eawt.ApplicationAdapter")});
method.invoke(application, new Object[]{adapter});
}
catch (Exception e)
{
e.printStackTrace();
}
}
StructorizerApplicationAdapter.java.txt
... but the trouble is that usually the system doesn't provide a Java compiler - so is bound to fail :-(.
I'm afraid there is no way to achieve the effect of conditional compilation while we have to use a subclass of a class the existence of which is not clear at compile time. If I'm right then we can forget about reflection here. (And by the way, a compilation at runtime is certainly not recommendable anyway, from both a performance and a security point of view. I had just tried to see if that way is possible at all.)
Bad hack: simply add an "empty" com.apple.eawt.*
package and have this in classpath exclusion for Apple Systems.
Or a little bit less hacky: move the apple code to a new source file that has a static function as entry. Then have two versions of this java class, one containing nothing the other one do the current calls.
Depending on the classpath setting the full one (and the additional apple-dependencies) are used or the other (that may raise a warning if apple os detected).
@GitMensch All these approaches mean to solve it in the configuration management, not in the code. Of course the code should support it in an elegant way, say some factories, mock interfaces, class name providers for reflection or whatsoever, to unify the Structorizer.java (which makes sense) but at some place or other in the project a subclass of an optionally available Apple-specific class must be defined and this code will blow the compilation in absence of the underlying Apple package. Some parameterized script or two versions of a project file or so will be necessary.
There could e.g. be some class ApplicationFactory
providing some Application
object for certain name, which responds to a method (may be a dummy or not) configureFor(Mainform mf)
allowing the following code:
if (System.getProperty("os.name").toLowerCase().startsWith("mac os x"))
{
ApplicationFactory.getApplication("apple").configureFor(mainform);
}
Some parameterized script or two versions of a project file or so will be necessary.
Yes, one needs the additional dependencies, the other one needs a classpath exclusion. It would be nice if you could provide the necessary code changes, the changes in the build scripts are then minimal, project files must be inspected (I don't know if Netbeans and Eclipse offer different configurations in the same project), or otherwise duplicated.
@GitMensch wrote:
It would be nice if you could provide the necessary code changes, the changes in the build scripts are then minimal, [...]
Well, I just set up a pull request https://github.com/fesch/Structorizer.Desktop/pull/593 addressing this. It may be tested in branch fesch/Structorizer.Desktop/make (where I directed it on purpose in order to keep the master branch clean of half-boiled code) if the pull would be accepted. With the changes in Structorizer.java I averted the impact of the sed command in makeStructorizer effectively by removing the marker comment. So the script or project file configuration is then up to you.
@codemanyak wrote:
Well, I just set up a pull request #593 addressing this. It may be tested in branch fesch/Structorizer.Desktop/make (where I directed it on purpose in order to keep the master branch clean of half-boiled code) if the pull would be accepted. With the changes in Structorizer.java I averted the impact of the sed command in makeStructorizer effectively by removing the marker comment.
You did more than that. With the new setup it doesn't matter if the AppleExtensions are not available as jar or not any more (both on compilation and on runtime) as long as the OS doesn't match osx. That is really good. I assume (did not test) that also everything will work (just without the extensions) if the jar/class is missing on osx.
So the script or project file configuration is then up to you.
Did, see PR #599.
@fesch
Maybe this will help ...
I guess the OSXAdapter
has the potential to facilitate your release process?
I might have a deeper look into it (somewhat later). Unfortunately I don't have an OS X development environment to test such an approach.
As far as I can see, Structorizer used to delegate its entire menu to the OS X application menu (in contrast to that myApp example), didn't it?
Yes, I've done the integration ... no push yet. I have developed a new launcher as replacement fir the JWS which will disappear quite soon ...
@fesch wrote:
Yes, I've done the integration ... no push yet.
So where do we stand here now?
So where do we stand here now?
I haven't done anything about it so far, and I am not even sure whether I should have. I got the impression that Bob is caring about it and I don't feel any stress here.
Steps I did locally: